验证c#中的模块和校验和

时间:2014-09-24 19:46:11

标签: c# ascii checksum

我正在使用一个嵌入式系统,该系统返回包含(我认为是)modular sum checksum的ASCII数据。我想验证这个校验和,但我根据制造商的规范无法做到这一点。我也无法完成相反的工作,并根据描述计算相同的校验和。

设备的每个响应都采用以下格式:

╔═════╦═══════════════╦════════════╦════╦══════════╦═════╗
║ SOH ║ Function Code ║ Data Field ║ && ║ Checksum ║ ETX ║
╚═════╩═══════════════╩════════════╩════╩══════════╩═════╝

示例:

SOHi11A0014092414220&&FBEA

SOH是ASCII 1.例如

#define SOH "\x01"

校验和的描述如下:

  

Checksum是一系列四个ASCII十六进制字符,用于检查前面所有字符的完整性,包括控件   字符。四个字符表示16位二进制计数,它是奇偶校验位(如果使能)被清除后消息字符的8位二进制表示的2的补码和。溢出被忽略。可以通过将四个校验和字符转换为16位来完成数据完整性检查   二进制数并将消息字符的8位二进制表示添加到其中。二进制结果应为零。

我尝试了对规范的一些不同解释,包括忽略SOH以及&符号,甚至功能代码。 此时我必须遗漏一些非常明显的内容,无论是我对规范的解释,还是我用来测试的代码。下面你会找到一个简单的例子(数据)是从实时系统中获取的,如果它是正确的,则validate变量中的低位字将为0

static void Main(string[] args)
{
    unchecked
    {
        var data = String.Format("{0}{1}", (char) 1, @"i11A0014092414220&&");
        const string checkSum = "FBEA";

        // Checksum is 16 bit word
        var checkSumValue = Convert.ToUInt16(checkSum, 16);

        // Sum of message chars preceeding checksum
        var mySum = data.TakeWhile(c => c != '&').Aggregate(0, (current, c) => current + c);
        var validate = checkSumValue + mySum;

        Console.WriteLine("Data: {0}", data);
        Console.WriteLine("Checksum: {0:X4}", checkSumValue);
        Console.WriteLine("Sum of chars: {0:X4}", mySum);
        Console.WriteLine("Validation: {0}", Convert.ToString(validate, 2));
        Console.ReadKey();
    }
}

修改

虽然@tinstaafl提供的解决方案适用于此特定示例,但在提供更大的记录时它不起作用,如下所示:

  

SOHi20100140924165011000007460904004608B40045361000427DDD6300000000427C3C66000000002200000745B4100045B3D8004508C00042754B900000000042774D8D0000000033000007453240004531E000459F5000420EA4E100000000427B14BB000000005500000744E0200044DF4000454AE000421318A0000000004288A998000000006600000744E8C00044E7200045469000421753E600000000428B4DA50000000&安培;&安培;

BA6C

理论上你可以继续递增/递减字符串中的值,直到校验和匹配为止,恰好使用字符1而不是ASCII SOH控制字符给它正确的值,在这种情况下是巧合。 / p>

1 个答案:

答案 0 :(得分:1)

不确定这是否正是您正在寻找的,但是通过使用1的整数表示SOH而不是char值为1,取所有字符的总和并转换{{1}变量为16位整数,我能够将验证等于0:

validate