I am trying to compare the MD5 string between PHP and Python, the server we have is working fine with PHP clients, but when we tried to do the same in python, we always get an invalid response from the server.
I have the following piece of code In Python
import hashlib
keyString = '96f6e3a1c4748b81e41ac58dcf6ecfa0'
decodeString = ''
length = len(keyString)
for i in range(0, length, 2):
subString1 = keyString[i:(i + 2)]
decodeString += chr(int(subString1, 16))
print(hashlib.md5(decodeString.encode("utf-8")).hexdigest())
Produces: 5a9536a1490714cb77a02080f902be4c
now, the same concept in PHP:
$serverRandom = "96f6e3a1c4748b81e41ac58dcf6ecfa0";
$length = strlen($serverRandom);
$server_rand_code = '';
for($i = 0; $i < $length; $i += 2)
{
$server_rand_code .= chr(hexdec(substr($serverRandom, $i, 2)));
}
echo 'SERVER CODE: '.md5($server_rand_code).'<br/>';
Produces: b761f889707191e6b96954c0da4800ee
I tried checking the encoding, but no luck, the two MD5 output don't match at all, any help?
Looks like your method of generating the byte string is incorrect, so the input to hashlib.md5 is wrong:
print(decodeString.encode('utf-8'))
# b'\xc2\x96\xc3\xb6\xc3\xa3\xc2\xa1\xc3\x84t\xc2\x8b\xc2\x81\xc3\xa4\x1a\xc3\x85\xc2\x8d\xc3\x8fn\xc3\x8f\xc2\xa0'
The easiest way to interpret the string as a hex string of bytes is to use binascii.unhexlify, or bytes.fromhex:
import binascii
decodeString = binascii.unhexlify(keyString)
decodeString2 = bytes.fromhex(keyString)
print(decodeString)
# b'\x96\xf6\xe3\xa1\xc4t\x8b\x81\xe4\x1a\xc5\x8d\xcfn\xcf\xa0'
print(decodeString == decodeString2)
# True
You can now directly use the resulting bytes object in hashlib.md5:
import hashlib
result = hashlib.md5(decodeString)
print(result.hexdigest())
# 'b761f889707191e6b96954c0da4800ee'
Related
I Want To Convert Text To Number Like in Python.
My Python Code:
from libnum import *
print(s2n("Text"))
# Output: 1415936116
print(s2n("\x31\x34\x31\x35\x39\x33\x36\x31\x31\x36"))
# Output: 1415936116
This is my php code. I went this far:
$String = "Text";
$Bytes = "";
$Length = strlen($String);
for ($i=0; $i<$Length; $i++) {
$Bytes .= "\x".(string)dechex(mb_ord($String[$i]));
}
echo $Bytes;
// Output: \x31\x34\x31\x35\x39\x33\x36\x31\x31\x36
You can convert strings to an integer using hexdec(bin2hex($string));
I fiddled around trying to figure out how to turn the packed hex string into an integer but couldn't figure out how to return the same integer as the string.
I am trying to decode a Base64 encoded byte string to a valid HTTP URL. I have tried appending necessary padding (=). But it still does not seem to work.
I have tried the following code.
import base64
encoded = b"aHR0cHM6Ly9mb3Jtcy5nbGUvWU5ZXQ0d2NRWHVLNnNwdjU="
decoded = base64.b64decode(encoded)
print(decoded)
The string encoded has a missing character as a part of noise. Is there a way to detect that missing character and then perform the decode operation?
So, you have this aHR0cHM6Ly9mb3Jtcy5nbGUvWU5ZXQ0d2NRWHVLNnNwdjU= base64 encoding of an URL with exactly one character missing.
For the missing character, you've 64 choices: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/ (for base64) and 48 possible positions to put the missing character in -a-H-R-0-c-H-M-6-L-y-9-m-b-3-J-t-c-y-5-n-b-G-U-v-W-U-5-Z-X-Q-0-d-2-N-R-W-H-V-L-N-n-N-w-d-j-U-=- (- indicates the possible positions)
So, you've 64 * 48 = 3072 possible encoded strings. Either you can try to generate them by your hand or write some code to do the same.
Once you generate them, you can decode the string to get the URL using some built-in libraries & check whether this URL is valid or not. If you also need to know whether this URL exists or not, you can make an HTTP request to the URL & check the response StatusCode.
Code:
package main
import (
"encoding/base64"
"fmt"
"net/http"
)
func main() {
encodedURL := "aHR0cHM6Ly9mb3Jtcy5nbGUvWU5ZXQ0d2NRWHVLNnNwdjU="
options := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
length := len(encodedURL)
for i := 0; i <= length; i++ {
for idx := 0; idx < 64; idx++ {
tempEncoded := encodedURL[:i] + options[idx:idx+1] + encodedURL[i:]
decodedURL, _ := base64.URLEncoding.DecodeString(tempEncoded)
resp, err := http.Get(string(decodedURL))
if err == nil && resp.StatusCode == http.StatusOK {
fmt.Println("this URL is valid & exists: ", string(decodedURL))
}
}
}
}
when the length of the unencoded input is not a multiple of three, the encoded output must have padding added so that its length is a multiple of four.
len(encoded) is 47, it should be 48, So append another =
encoded = b"aHR0cHM6Ly9mb3Jtcy5nbGUvWU5ZXQ0d2NRWHVLNnNwdjU=="
print(decoded)
b'https://forms.gle/YNY]\r\x1d\xd8\xd4V\x1dR\xcd\x9c\xdc\x1d\x8d'
I have the following Python code:
array_to_return = dict()
response_json_object = json.loads(responsestring)
for section in response_json_object:
if section["requestMethod"] == "getPlayerResources":
array_to_return["resource_list"] = json.dumps(section["responseData"]["resources"])
break
array_to_return["requests_duration"] = time.time() - requests_start_time
array_to_return["python_duration"] = time.time() - python_start_time
Which returns the following content into a PHP script:
{'resource_list': '{"aaa": 120, "bbb": 20, "ccc": 2138, "ddd": 8}', 'requests_duration': '7.30', 'python_duration': 41.0}
I'm then trying to decode this string and convert it into something usable in PHP. My code if the following:
$cmd = "$python $pyscript";
exec("$cmd", $output);
echo 'output: ';
var_dump($output[0]);
$json_output = json_decode($output[0], true);
echo 'json_output: ';
var_dump($json_output, json_last_error_msg());
$output[0] is a string but json_last_error_msg() returns Syntax Error
I'm well aware that my string is not a valid Json string, but how can I convert it properly (either in Python or in PHP)? I probably do something wrong in my Python script...
UPDATE 1:
I actually found out that responsestring is a valid JSON string (with double quotes) but json.loads switches the double to single quotes; thus response_json_object has single quotes.
If I comment out the line with json.loads, I get an error:
TypeError: 'int' object is not subscriptable
UPDATE 2:
I managed to get around it by removing the associative list in Python, not exactly what I was hoping for but this works for now...
array_to_return = json.dumps(section["responseData"]["resources"])
#No longer using the following
#array_to_return["requests_duration"] = time.time() - requests_start_time
#array_to_return["python_duration"] = time.time() - python_start_time
If a working solution with associative list is suggested, I will accept that one.
The ' character is not a legal character for JSON, it must be a ".
Your json should look like this.
{
"resource_list": "{\"aaa\": 120, \"bbb\": 20, \"ccc\": 2138, \"ddd\": 8}",
"requests_duration": "7.30",
"python_duration": 41.0
}
instead of modifying the individual key, value pairs of array_to_return by json.dumps, you would json.dumps the whole dictionary.
array_to_return = dict()
response_json_object = json.loads(responsestring)
for section in response_json_object:
if section["requestMethod"] == "getPlayerResources":
array_to_return["resource_list"] = json.dumps(section["responseData"]["resources"])
array_to_return["resource_list"] = section["responseData"]["resources"]
break
array_to_return["requests_duration"] = time.time() - requests_start_time
array_to_return["python_duration"] = time.time() - python_start_time
json.dumps(array_to_return)
I'm trying to get message digest of a string on IOS. I have tried nv-ios-digest 3rd party Hash lib but still no use.
Below is the function i'm using to get the base64encoded string of a message digest.
-(NSString*) sha1:(NSString*)input //sha1- Digest
{
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++){
[output appendFormat:#"%02x", digest[i]];//digest
}
return [NSString stringWithFormat:#"%#",[[[output description] dataUsingEncoding:NSUTF8StringEncoding]base64EncodedStringWithOptions:0]]; //base64 encoded
}
Here is my sample input string - '530279591878676249714013992002683ec3a85216db22238a12fcf11a07606ecbfb57b5'
When I use this string either in java or python I get same result - '5VNqZRB1JiRUieUj0DufgeUbuHQ='
But in IOS I get 'ZTU1MzZhNjUxMDc1MjYyNDU0ODllNTIzZDAzYjlmODFlNTFiYjg3NA=='
Here is the code I'm using in python:
import hashlib
import base64
def checkForDigestKey(somestring):
msgDigest = hashlib.sha1()
msgDigest.update(somestring)
print base64.b64encode(msgDigest.digest())
Let me know if there is anyway to get the same result for IOS.
You are producing a binary digest in Python, a hexadecimal digest in iOS.
The digests are otherwise equal:
>>> # iOS-produced base64 value
...
>>> 'ZTU1MzZhNjUxMDc1MjYyNDU0ODllNTIzZDAzYjlmODFlNTFiYjg3NA=='.decode('base64')
'e5536a65107526245489e523d03b9f81e51bb874'
>>> # Python-produced base64 value
...
>>> '5VNqZRB1JiRUieUj0DufgeUbuHQ='.decode('base64')
'\xe5Sje\x10u&$T\x89\xe5#\xd0;\x9f\x81\xe5\x1b\xb8t'
>>> from binascii import hexlify
>>> # Python-produced value converted to a hex representation
...
>>> hexlify('5VNqZRB1JiRUieUj0DufgeUbuHQ='.decode('base64'))
'e5536a65107526245489e523d03b9f81e51bb874'
Use base64.b64encode(msgDigest.hexdigest()) in Python to produce the same value, or Base-64 encode the digest bytes instead of hexadecimal characters in iOS.
I need help converting the following PHP to python
$plaintext = "MyPassword";
$utf_text = mb_convert_encoding( $plaintext, 'UTF-16LE' );
$sha1_text = sha1( $utf_text, true );
$base64_text = base64_encode( $sha1_text );
echo $base64_text; //ouput = QEy4TXy9dNgleLq+IEcjsQDYm0A=
Convert the string to UTF16LE
Hash the output of 1. using SHA1
Encode the output of 2. using base64 encoding.
Im trying hashlib.sha1 but its not working. Maybe due to this, maybe encodings. Can anyone help
Your PHP code encodes the password to UTF16, little endian; if your password value is a unicode value, that works just fine in Python:
>>> import hashlib
>>> plaintext = u"MyPassword"
>>> utf_text = plaintext.encode('UTF-16LE')
>>> hashlib.sha1(utf_text).digest().encode('base64')
'QEy4TXy9dNgleLq+IEcjsQDYm0A=\n'
The above session was done in Python 2; in Python 3 the u prefix can be omitted as all string values are Unicode.
Got it, i was using the hashlib.sha1 incorrectly.
import hashlib
password = "MYPASSWORD"
result ='QEy4TXy9dNgleLq+IEcjsQDYm0A='
utftext = password.encode("utf-16LE")
m = hashlib.sha1()
m.update(utftext)
sha1text = m.digest()
output = sha1text.encode('base64','strict')
print "output: %s" % output
print "expect: %s" % result
I don't see why this wouldn't work. This works like a charm and prints out the desired result, QEy4TXy9dNgleLq+IEcjsQDYm0A=
from hashlib import sha1
from base64 import b64encode
print(b64encode(sha1("MyPassword".encode("utf-16le")).digest()))