这是我在C#中的代码:
public static String MD5Encrypt(String str, Boolean raw_output=false)
{
// Use input string to calculate MD5 hash
String output;
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(str);
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"));
}
output = sb.ToString();
if (raw_output)
{
output = pack(output);
}
return output;
}
public static String pack(String S)
{
string MultiByte = "";
for (int i = 0; i <= S.Length - 1; i += 2)
{
MultiByte += Convert.ToChar(HexToDec(S.Substring(i, 2)));
}
return MultiByte;
}
private static int HexToDec(String hex)
{
//Int32.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
return Convert.ToInt32(hex, 16);
}
通过这种方式重现php中的内容:
md5($str, true);
OR
pack('H*', md5( $str ));
我尝试过很多东西,但在某些情况下,双方都无法达到相同的效果。 例如,在字符串“8tv7er5j”
上尝试此测试PHP方面:
9c36ad446f83ca38619e12d9e1b3c39e <= md5("8tv7er5j");
œ6DoƒÊ8ažÙá³Ãž <= md5("8tv7er5j", true) or pack("H*", md5("8tv7er5j"))
C#Side :
9c36ad446f83ca38619e12d9e1b3c39e <= MD5Encrypt("8tv7er5j")
6DoÊ8aÙá³Ã <= MD5Encrypt("8tv7er5j", true) or pack( MD5Encrypt("8tv7er5j") )
为什么?编码问题?
编辑1: 我有很好的结果,但是这个函数对pack()进行了编码:
if ((hex.Length % 2) == 1) hex += '0';
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
所以,System.Text.Encoding.UTF8.GetString(bytes)给了我: 6Do8aÞ
System.Text.Encoding.ASCII.GetString(bytes) →6→做?? 8A ??????
...
答案 0 :(得分:1)
我遇到了同样的情况,我需要在C#中使用php的pack-unpack-md5函数。最重要的是我需要用php匹配所有这三个函数。
我创建了自己的函数,然后使用onlinephpfunctions.com上的函数验证(验证)了我的输出。使用DefaultEncoding解析时输出相同。仅供参考,我检查了应用程序的编码( Encoding.Default.ToString()),它是 System.Text.SBCSCodePageEncoding
<强>包强>
private static string pack(string input)
{
//only for H32 & H*
return Encoding.Default.GetString(FromHex(input));
}
public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
<强> MD5 强>
private static string md5(string input)
{
byte[] asciiBytes = Encoding.Default.GetBytes(input);
byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
return hashedString;
}
<强>解压强>
private static string unpack(string p1,string input) { StringBuilder输出= new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
string a = Convert.ToInt32(input[i]).ToString("X");
output.Append(a);
}
return output.ToString();
}
PS:用户可以使用其他格式增强这些功能
答案 1 :(得分:0)
我猜PHP默认为Latin1,因此代码应如下所示:
public static String PhpMd5Raw(string str)
{
var md5 = System.Security.Cryptography.MD5.Create();
var inputBytes = System.Text.Encoding.ASCII.GetBytes(str);
var hashBytes = md5.ComputeHash(inputBytes);
var latin1Encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
return latin1Encoding.GetString(hashBytes);
}
答案 2 :(得分:0)
如果要将结果作为HMAC-SHA1散列的密钥提供,请将其保留为bytes []并使用此函数的返回值初始化HMACSHA1:不要将其转换为字符串并返回字节,I因为这个错误而花了好几个小时。
public static byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
答案 3 :(得分:0)
我知道这是一个老问题。我将答案发布给可能到达此页面进行搜索的任何人。 以下代码是珍珠功能包(“ H *”)到c#的完全转换。
public static String Pack(String input)
{
input = input.Replace("-", " ");
byte[] hashBytes = new byte[input.Length / 2];
for (int i = 0; i < hashBytes.Length; i++)
{
hashBytes[i] = Convert.ToByte(input.Substring(i * 2, 2), 16);
}
return Encoding.UTF7.GetString(hashBytes); // for perl/php
}
答案 4 :(得分:0)
对不起。我没有完全解决这些问题。但是,如果php代码如下,
$testpack = pack("H*" , "you value");
如果由于某些不支持的格式而无法读取$ testpack值,则首先按如下所示执行base64_encode并将其回显。
echo base64_encode($testpack);
然后使用 Risky Pathak 答案。为了完整地回答这个问题,我将对他的回答进行一些小的修改,例如base 64编码等。
var hex = "you value";
hex = hex.Replace("-", "");
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
var res = Convert.ToBase64String(raw);
Console.WriteLine(res);
现在,如果您同时比较两个值,则这些值应该相似。
所有功劳应归于 Risky Pathak 答案。