Please help me convert below JS code to Python.
const di_digest = CryptoJS.SHA1(di_plainTextDigest).toString(CryptoJS.enc.Base64);
di_plainTextDigest is a String.
I tried a few Python methods, but not working. Example
result = hashlib.sha1(di_plainTextDigest.encode())
hexd = result.hexdigest()
hexd_ascii = hexd.encode("ascii")
dig2 = base64.b64encode(hexd_ascii)
dig3 = dig2.decode("ascii")
print(dig3 )
To replicate the functionality of the JavaScript code in Python, you can use the hashlib and base64 modules as you have attempted to do. However, the difference between your Python code and the JavaScript code is in the encoding format used. In the JavaScript code, the di_plainTextDigest is encoded using the Base64 format, whereas in your Python code, you are encoding the SHA1 hash of di_plainTextDigest as a hex string before encoding it in Base64. To replicate the JavaScript code in Python, you can skip the hex encoding step and directly encode the SHA1 hash of di_plainTextDigest in Base64. Here is the Python code that should produce the same result as the JavaScript code:
import hashlib
import base64
di_plainTextDigest = "your plaintext digest"
sha1_hash = hashlib.sha1(di_plainTextDigest.encode())
base64_hash = base64.b64encode(sha1_hash.digest()).decode('ascii')
print(base64_hash)
Note that we are encoding the digest() of the sha1_hash object, instead of its hexdigest(). This is because hexdigest() returns a hex-encoded string, whereas we want to produce a Base64-encoded string. We also use the decode() method to convert the resulting bytes object to a string in ASCII format.
Related
I'm using Java and I have a Base64 encoded string that I wish to decode and then do some operations to transform.
The correct decoded value is obtained in JavaScript through function atob(), but in java, using Base64.decodeBase64() I cannot get an equal value.
Example:
For:
String str = "AAAAAAAAAAAAAAAAAAAAAMaR+ySCU0Yzq+AV9pNCCOI="
With JavaScript atob(str) I get ->
"Æ‘û$‚SF3«àö“Bâ"
With Java new String(Base64.decodeBase64(str)) I get ->
"Æ?û$?SF3«à§ö?â"
Another way I could fixed the issue is to run JavaScript in Java with a Nashorn engine, but I'm getting an error near the "$" symbol.
Current Code:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
String script2 = "function decoMemo(memoStr){ print(atob(memoStr).split('')" +
".map((aChar) => `0${aChar.charCodeAt(0).toString(16)}`" +
".slice(-2)).join('').toUpperCase());}";
try {
engine.eval(script2);
Invocable inv = (Invocable) engine;
String returnValue = (String)inv.invokeFunction("decoMemo", memoTest );
System.out.print("\n result: " + returnValue);
} catch (ScriptException | NoSuchMethodException e1) {
e1.printStackTrace();
Any help would be appreciated. I search a lot of places but can't find the correct answer.
btoa is broken and shouldn't be used.
The problem is, bytes aren't characters. Base64 encoding does only one thing. It converts bytes to a stream of characters that survive just about any text-based transport mechanism. And Base64 decoding does that one thing in reverse, it converts such characters into bytes.
And the confusion is, you're printing those bytes as if they are characters. They are not.
You end up with the exact same bytes, but javascript and java disagree on how you're supposed to turn that into an ersatz string because you're trying to print it to a console. That's a mistake - bytes aren't characters. Thus, some sort of charset encoding is being used, and you don't want any of this, because these characters clearly aren't intended to be printed like that.
Javascript sort of half-equates characters and bytes and will freely convert one to the other, picking some random encoding. Oof. Javascript sucks in this regard, it is what it is. The MDN docs on btoa explains why you shouldn't use it. You're running into that problem.
Not entirely sure how you fix it in javascript - but perhaps you don't need it. Java is decoding the bytes perfectly well, as is javascript, but javascript then turns those bytes into characters into some silly fashion and that's causing the problem.
What you have there is not a text string at all. The giveaway is the AA's at the beginning. Those map to a number of zero bytes. That doesn't translate to meaningful text in any standard character set.
So what you have there is most likely binary data. Converting it to a string is not going to give you meaningful text.
Now to explain the difference you are seeing between Java and Javascript. It looks to me as if both Java and Javascript are making a "best effort" attempt to convert the binary data as if is was encoded in ISO-8859-1 (aka ISO LATIN-1).
The problem is some of the bytes codes are mapping to unassigned codes.
In the Java case those unassigned codes are being mapped to ?, either when the string is created or when it is being output.
In the Javascript case, either the unassigned codes are not included in the string, or them are being removed when you attempt to display them.
For the record, this is how an online base64 decoder the above for me:
����������������Æû$SF3«àöBâ
The unassigned codes are 0x91 0x82 and 0x93. 0x15 and 0x0B are non-printing control codes.
But the bottom line is that you should not be converting this data into a string in either Java or in Javascript. It should be treated as binary; i.e. an array of byte values.
byte[] data = Base64.getDecoder().decode(str);
I have an encoded string as follows:
S0VEQUkgUlVOQ0lUIFZSSU5FIEVOVEVSUFJJU0UgLSBLRyBTSU1QQU5HIDQgU09PSw
This was encoded using JavaScript btoa() function. This string can be correctly decoded using JavaScript atob() function. It should give the following decoded string :
KEDAI RUNCIT VRINE ENTERPRISE - KG SIMPANG 4 SOOK
Right now I'm developing Android app and I have to decode this string, I'm using the following to decode :
java.util.Base64.getDecoder().decode(encodedstring).toString();
I'm not getting the correct decoded output. Anyone knows what's the problem ? Is it even possible to decode using Java ?
decode(String) returns a byte[], you need to convert that to a string using a String constructor and not the toString() method:
byte[] bytes = java.util.Base64.getDecoder().decode(encodedstring);
String s = new String(bytes, java.nio.charset.StandardCharsets.UTF_8);
It looks like you need mime decoder message
java.util.Base64.Decoder decoder = java.util.Base64.getMimeDecoder();
// Decoding MIME encoded message
String dStr = new String(decoder.decode(encodedstring));
System.out.println("Decoded message: "+dStr);
I am working on reading hexdecimal code from sql server and convert that hexadecimal code to XML format In ReactJS
For converting i am using this below code, it returning xml but in that returned xml with lot of symbols are there,
var hex = 'PEVycm9yPg0KWE1MIGRvY3VtZW50IG11c3QgaGF2ZSBhIHRvcCBsZXZlbCBlbGVtZW50Lg0KDQpMaW5lOiAwDQoNCjwvRXJyb3I+DQo='
hexaToString(hex) {
var str = '';
for (var i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
for above code i am getting below xml format with symbols
https://codebeautify.org/hex-string-converter
how to remove those symbols, why i am getting those symbols, how to overcome this issue.
Please can anyone help me.
The string you are trying to decode isn't in hexadecimal format, it's in Base64.
Most of the characters in your string hex aren't valid hexadecimal characters. Somewhat unhelpfully, JavaScript doesn't report any errors attempting to parse invalid hex digits or create characters from the resulting nonsense:
console.log(parseInt("PE", 16)); // logs 'NaN'
String.fromCharCode(NaN); // logs character with code 0
To decode the string from Base64, use the atob function. console.log(atob(hex)); logs the following:
<Error>
XML document must have a top level element.
Line: 0
</Error>
Your string hex contains an error message encoded in Base64.
The CodeBeautify tool you link to also has a Base64 decoder, which generates the same output.
I am trying to derive a bitcoin address from a known public key. When hashing the public key with CryptoJS.SHA256 I don't get the expected result
CryptoJS.SHA256("0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6").toString(CryptoJS.enc.Hex)
gets me:
32511e82d56dcea68eb774094e25bab0f8bdd9bc1eca1ceeda38c7a43aceddce
while i am trying to get:
600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
What am I missing?
It's just an encoding issue - don't try to hash the hex, hash the binary.
For example, here is the hash computation when you decode the hex into binary (using Haskell since I have it handy):
Prelude> import Crypto.Hash.SHA256
Prelude Crypto.Hash.SHA256> let str = "0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6"
Prelude Crypto.Hash.SHA256> Data.ByteString.Base16.encode $ hash $ fst $ Data.ByteString.Base16.decode $ Data.ByteString.Char8.pack str
"600ffe422b4e00731a59557a5cca46cc183944191006324a447bdb2d98d4b408"
What I need to do is best descriped as example.
Previously, I had the following code:
content = u'<?xml version="1.0" encoding="windows-1251"?>\n' + ... #
with open(file_name, 'w') as f:
f.write(content.encode('cp1251'))
f.close;
Now I want to modify the architecture of my entire app and send the string which is supposed to be the file content to client via JSON and to generate the file via javascript.
So, now my code looks something like this:
response_data = {}
response_data['file_content'] = content.encode('cp1251')
response_data['file_name'] = file_name
return JsonResponse({'content':json.dumps(response_data, ensure_ascii=False)}) # error generated
The problem is that I get UnicodeDecodeError: 'ascii' codec can't decode byte 0xd4 in position 53: ordinal not in range(128)
I also tried the second option this way:
response_data = {}
response_data['file_content'] = content
response_data['file_name'] = file_name
return JsonResponse({'content':json.dumps(response_data, ensure_ascii=False).encode('utf8')}) # error generated
Then, on client, I try to covert utf8 to windows-1251.
$.post ('/my_url/', data, function(response) {
var file_content = JSON.parse(response.content).file_content;
file_content = UnicodeToWin1251(file_content);
...but...I get distorted symbols.
I know I am doing something terribly wrong here and am likely to mess up things with encoding, but still it's been an entire day I couldn't solve this issue. Could someone give a hint where my mistake is ?
Both XML and JSON contain data that is Unicode text. The XML declaration merely tells your XML parser how to decode the XML serialisation of that data. You wrote the serialisation by hand so to match the XML header, you had to encode to CP-1251.
The JSON standard states that all JSON should be encoded in either UTF-8, UTF-16 or UTF-32, with UTF-8 the standard; again, this is just the encoding for the serialisation.
Leave your data as Unicode, then encode that data to JSON with the json library; the library takes care of ensuring you get UTF-8 data (in Python 2), or gives you Unicode text (Python 3) that can be encoded to UTF-8 later. Your Javascript code will then decode the JSON again at which point you have Unicode text again:
response_data = {}
response_data['file_content'] = content
response_data['file_name'] = file_name
return JsonResponse({'content':json.dumps(response_data, ensure_ascii=False)})
There is no need whatsoever to send binary data over JSON here, you are sending text. If you Javascript code then generates the file, it is responsible for encoding to CP-1251, not your Python code.
If you must put binary data in a JSON payload, you'll need to encode that payload to some form of text. Binary data (and CP-1251-encoded text is binary data) could be encoded in text as Base-64:
import base64
response_data = {}
response_data['file_content'] = base64.encodestring(content.encode('cp1251')).decode('ascii')
response_data['file_name'] = file_name
return JsonResponse({'content':json.dumps(response_data, ensure_ascii=False)})
Base64 data is encoded to a bytestring containing only ASCII data, so decode it as ASCII for the JSON library, which expects text to be Unicode text.
Now you are sending binary data, wrapped in a Base64 text encoding, to the Javascript client, which now has to decode the Base64 if you need the binary payload there.