4

文字列「0AAE0000463130004144430000」があり、文字列を構成する16進バイトの2の補数チェックサムを計算する必要があります。

上記の文字列の例の式は次のとおりです。

  1. 値を合計します:0A + AE + 00 + 00 + 46 + 31 + 30 + 00 + 41 + 44 + 43 + 00 + 00 = 27(オーバーフローを破棄します)
  2. 0x100=0xD9から結果を減算します

D9はこの例の正しいチェックサムですが、C#の文字列から2桁の16進値を解析するのに問題があります。私の現在のコードは以下の通りです:

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を使用して一度に2文字を取得し、NumberStyles.AllowHexSpecifierを指定したint.Parseを使用して、文字のペアを16進値として読み取ります。

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 に答える