我正致力于将用PHP编写的加密库转换为C#,并且遇到一个小问题。在PHP中将HEX字符串转换为字符串时,我得到一个不同的值,然后我的C#代码应该做同样的事情。
这是我正在使用的PHP代码:
public function hex2str($hex)
{
$str = '';
for($i=0; $i<strlen($hex); $i+=2)
{
$str.=chr(hexdec(substr($hex, $i, 2)));
}
return $str;
}
我的C#代码:
public static string Hex2Str(string hexString)
{
char[] mychar = new char[hexString.Length / 2];
for (var i = 0; i < mychar.Length; i++)
{
// Convert the number expressed in base-16 to an integer.
int value = Convert.ToInt32(hexString.Substring(i * 2, 2), 16);
string stringValue = Char.ConvertFromUtf32(value);
mychar[i] = (char)value;
}
return new String(mychar);
}
使用的十六进制值是:
E0D644FCDEB4CCA04D51F617D59084D8
这是PHP脚本和我的C#脚本返回值之间差异的图片:
如果有人能帮助我发现我在C#代码中的错误,我将非常感谢您的帮助!
答案 0 :(得分:1)
区别在于使用的不同代码页。似乎PHP使用OEM字符集(代码页850),它仍然与默认命令行一起使用。
你可以试试这个:
public static string Hex2Str(string hexString)
{
byte[] myBytes = new byte[hexString.Length / 2];
for (var i = 0; i < myBytes.Length; i++)
{
// Convert the number expressed in base-16 to an integer.
int value = Convert.ToInt32(hexString.Substring(i * 2, 2), 16);
myBytes[i] = (byte)value;
}
return Encoding.GetEncoding(850).GetString(myBytes);
}
请注意,计算机上实际使用的编码取决于本地设置。
您还可以更改代码页或使用其中一种标准编码:
return Encoding.Default.GetString(myBytes);
这个可能会给你第一次尝试的初步结果。
另请注意,大概使用php写入文件会产生另一个结果,而不是在命令行中打印到stdio。
答案 1 :(得分:1)
我认为您的c#算法Hex2Str
看起来不错,但我可能会建议进行以下小改动以避免与代理对编码存在任何可能的不一致:
public static string Hex2Str(string hexString)
{
var sb = new StringBuilder();
var len = hexString.Length / 2;
for (var i = 0; i < len; i++)
{
// Convert the number expressed in base-16 to an integer.
int value = Convert.ToInt32(hexString.Substring(i * 2, 2), 16);
string stringValue = Char.ConvertFromUtf32(value);
sb.Append(stringValue);
}
return sb.ToString();
}
我怀疑这里的真正问题是,由于编码不一致,PHP中的字符串在通过控制台时会被破坏。例如,如果PHP控制台具有Latin 9 (ISO)
编码并且您的输入控制台具有OEM United States
编码(它在我的计算机上),则'à'将转换为'α'。
相反,我建议在将其写入控制台之前,使用base64_encode
在Base64中编写PHP字符串的附加步骤。这将保证在通过控制台传递时的纯ASCII表示。然后解码如下:
public static string FromPHPBase64String(string phpString)
{
var bytes = Convert.FromBase64String(phpString);
var sb = new StringBuilder();
foreach (var b in bytes)
{
string stringValue = char.ConvertFromUtf32(b);
sb.Append(sb);
}
return sb.ToString();
}
我相信现在一切都应该匹配。