我有一个字符串“0AAE0000463130004144430000”,我需要计算组成字符串的十六进制字节的二进制补码校验和。
上面示例字符串的公式是
D9是此示例的正确校验和,但我无法从C#中的字符串中解析出两位十六进制值。我目前的代码如下:
string output = "0AAE0000463130004144430000";
long checksum = 0;
char[] outputBytes = output.TrimStart(':').ToCharArray();
foreach (var outputByte in outputBytes)
{
checksum += Convert.ToInt32(outputByte);
checksum = checksum & 0xFF;
}
checksum = 256 - checksum;
然而,这是我可以告诉的ASCII值的总和,并为每个单独的角色做。
答案 0 :(得分:10)
您可以在System.Runtime.Remoting.Metadata.W3cXsd2001中使用SoapHexBinary
类。
soapHexBinary.Value
属性将返回一个字节数组
string hexString = "0AAE0000463130004144430000";
byte[] buf = SoapHexBinary.Parse(hexString).Value;
int chkSum = buf.Aggregate(0, (s, b) => s += b) & 0xff;
chkSum = (0x100 - chkSum) & 0xff;
var str = chkSum.ToString("X2"); // <-- D9
答案 1 :(得分:2)
试试这个。使用SubString一次抓取两个字符,并使用带有NumberStyles.AllowHexSpecifier的int.Parse将这对字符作为十六进制值读取。
string output = "0AAE0000463130004144430000";
int checksum = 0;
// You'll need to add error checking that the string only contains [0-9A-F],
// is an even number of characters, etc.
for(int i = 0; i < output.length; i+=2)
{
int value = int.Parse(output.SubString(i, 2), NumberStyles.AllowHexSpecifier);
checksum = (checksum + value) & 0xFF;
}
checksum = 256 - checksum;
答案 2 :(得分:0)
如果要包含System.Runtime.Remoting.Metadata.W3cXsd2001
名称空间,则可接受的答案有效。
如果不想包含名称空间,则以下代码将返回正确的结果。此示例与上面的示例之间的区别是添加到返回值的附加& 0xFF
。否则,计算针对全零的校验和时,结果将不正确。
public static class ExtensionMethods
{
public static string MicrochipDataString(this string input)
{
int TwosComplement(string s)
{
if (s.Length % 2 != 0)
throw new FormatException(nameof(input));
var checksum = 0;
for (var i = 0; i < s.Length; i += 2)
{
var value = int.Parse(s.Substring(i, 2), NumberStyles.AllowHexSpecifier);
checksum = (checksum + value) & 0xFF;
}
return 256 - checksum & 0xFF;
}
return string.Concat(":", input, TwosComplement(input).ToString("X2"));
}
}