Reputation: 133
I have this C# code:
public static string Encript(string strData)
{
string hashValue = HashData(strData);
string hexHashData = ConvertStringToHex(hashValue);
return hexHashData;
}
public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
return System.Text.Encoding.Unicode.GetString(byteHashValue);
}
public static string ConvertStringToHex(string asciiString)
{
string hex = "";
foreach (char c in asciiString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint) System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}
Here you can see an online version.As you can see for the string "test" I get the output "5c82e9e41c7599f790ef1d774b7e6bf" And this is what I tried on php side
$a = "test";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a);
echo $a;
But the value of the php code is "c8059e2ec7419f590e79d7f1b774bfe6".Why is not working?
Edit:Looks like the C# code is incorrect and needs to be replaced
Upvotes: 3
Views: 4105
Reputation: 17407
The problem in your case is not the encoding, but your conversion to string on the C# side. As long as you use the same encoding everywhere, it should work as expected. But note, that most of the online hashers use ASCII
encoding, whereas you use System.Text.Encoding.Unicode
which is UTF-16, thus the results will differ from the online encoders.
The code below will give the same result as your PHP snippet (ie c8059e2ec7419f590e79d7f1b774bfe6
)
public static void Main(string[] args)
{
string a = "test";
string en = HashData(a);
Console.WriteLine(en);
}
public static string HashData(string textToBeEncripted)
{
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (var b in byteHashValue)
s.Append(b.ToString("x2"));
return s.ToString();
}
If you use System.Text.Encoding.ASCII
instead, you will get 098f6bcd4621d373cade4e832627b4f6
as suggested in other answers. But then you'll have to use ASCII encoding in your PHP code as well.
This is because with UTF16 every character is represented by two bytes, and not only by one. Thus the byteDataToHash
will have twice the size ([116, 0, 101, 0, 115, 0, 116, 0]
vs [116, 101, 115, 116]
in your case). And a different bytevector of course leads to a different hashvalue. But as said above, as long as all included components use the same encoding, it does not really matter which one you use.
Upvotes: 1
Reputation: 134085
The problem is that you are converting the result incorrectly in your C# code. If you put a breakpoint in the code after you call ComputeHash
, and examine the value of byteHashValue
, you'll see that it's c8059e2e...
.
Or, just add this code to your ComputeHash
method:
Console.WriteLine(BitConverter.ToString(byteHashValue));
I would suggest rewriting your code to be:
public static string Encript(string strData)
{
string hashValue = HashData(strData);
return hashValue;
}
public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
return BitConverter.ToString(byteHashValue).Replace("-", "");
}
Oh, and a side note: the word is "Encrypt," not "Encript."
Upvotes: 1
Reputation: 1577
The correct MD5 hash for 'test' is '098f6bcd4621d373cade4e832627b4f6' in PHP.
I tested it with this code in C#
public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
It will generate the same hash as PHP will, without the 'convert encoding' method you are using.
Upvotes: 6
Reputation: 74
I believe converting the encoding is what is giving you a different answer, try it without
$a = mb_convert_encoding($a, "UTF-16LE");
Upvotes: 2