I am trying to port parts of a ruby project to python and cannot figure out the equivalent to Base64.urlsafe_encode64(Digest::SHA256.hexdigest(STRING))
Closest I have gotten is base64.urlsafe_b64encode(hashlib.sha256(STRING.encode('utf-8')).digest())
however giving the input of StackOverflow
it returns: b'HFqE4xhK0TPtcmK7rNQMl3bsQRnD-sNum5_K9vY1G98='
for Python and MWM1YTg0ZTMxODRhZDEzM2VkNzI2MmJiYWNkNDBjOTc3NmVjNDExOWMzZmFjMzZlOWI5ZmNhZjZmNjM1MWJkZg==
in Ruby.
Full Python & Ruby Code:
Ruby
require "base64"
require "digest"
string= "StackOverflow"
output= Base64.urlsafe_encode64(Digest::SHA256.hexdigest(string))
puts output
Python
import hashlib
import base64
string = str("StackOverflow")
output = base64.urlsafe_b64encode(hashlib.sha256(string.encode('utf-8')).digest())
print(str(output))
CodePudding user response:
In your original Python code, you used digest
instead of hexdigest
which will give different results, as it's not the same thing. Keep in mind that converting code to different languages can be very difficult, as you need to understand both languages well enough to compare the code. Try and dissect the code piece by piece, splitting lines and printing each strings output / giving output at each stage to check what is happening.
Jamming everything into one line can be messy and you can easily overlook different factors which could play a major role in bug fixing.
You should write your code "spaced-out" at first, and in production you can change the code to be a singular line, although it's not very readable with long code.
What you are looking for is:
string = str("StackOverflow")
output = hashlib.sha256(code_verifier.encode('utf-8')).hexdigest()
output = base64.urlsafe_b64encode(code_challenge.encode('utf-8'))
print(str(output.decode('utf-8')))
It gives the same result, as if you are using Base64.urlsafe_encode64(Digest::SHA256.hexdigest(string))
in ruby.
CodePudding user response:
You need to use the hexdigest
method instead of digest
on the hash in Python to get the same output as in your Ruby example (since you use the hexdigest
function there).
Also note that the hexdigest
method returns a string instead of bytes, so you'll need to encode the result again (with .encode("utf-8")
).
Here's a full example:
import hashlib
import base64
string = "StackOverflow"
output = base64.urlsafe_b64encode(hashlib.sha256(string.encode("utf-8")).hexdigest().encode("utf-8"))
print(str(output))