问题
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
- Sum the values: 0A + AE + 00 + 00 + 46 + 31 + 30 + 00 + 41 + 44 + 43 + 00 + 00 = 27 (discard the overflow)
- 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