4

我有一个字符串“0AAE0000463130004144430000”,我需要计算构成该字符串的十六进制字节的二进制补码校验和。

上面示例字符串的公式是

  1. 将值相加:0A + AE + 00 + 00 + 46 + 31 + 30 + 00 + 41 + 44 + 43 + 00 + 00 = 27(丢弃溢出)
  2. 从 0x100 = 0xD9 中减去结果

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 值求和,并对每个单独的字符进行求和。

4

3 回答 3

11

您可以使用SoapHexBinarySystem.Runtime.Remoting.Metadata.W3cXsd2001 中的类。

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
于 2012-10-17T20:42:10.407 回答
2

试试这个。使用 SubString 一次抓取两个字符,并使用 int.Parse 和 NumberStyles.AllowHexSpecifier 将这对字符读取为十六进制值。

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;
于 2012-10-17T20:42:04.993 回答
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"));
    }
}
于 2018-11-05T17:39:18.913 回答