Calculate two's complement checksum of hexadecimal string

混江龙づ霸主 提交于 2019-12-01 04:30:22

问题


I have a string "0AAE0000463130004144430000" and I need to calculate the two's complement checksum of the hex bytes that make up the string.

The formula for the example string above is

  1. Sum the values: 0A + AE + 00 + 00 + 46 + 31 + 30 + 00 + 41 + 44 + 43 + 00 + 00 = 27 (discard the overflow)
  2. Subtract the result from 0x100 = 0xD9

D9 is the correct checksum for this example, but I am having trouble getting the two digit hex values parsed out of the string in C#. My current code is below:

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;

However, this is summing the ASCII values as far as I can tell, and doing it for each individual character.


回答1:


You can use SoapHexBinary class in System.Runtime.Remoting.Metadata.W3cXsd2001.

soapHexBinary.Value property will return you a byte array

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



回答2:


Try this instead. Grab two characters at a time using SubString, and read the pair of characters as a hex value using int.Parse with 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;



回答3:


The accepted answer works if you want to include the System.Runtime.Remoting.Metadata.W3cXsd2001 namespace.

If you do not want to include the namespace, the following code will return the correct results. The difference between this example and the example above is the additional & 0xFF added to the return value. Without this, you will incorrect results when calculating the checksum against all zeros.

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"));
    }
}


来源:https://stackoverflow.com/questions/12942904/calculate-twos-complement-checksum-of-hexadecimal-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!