我该如何计算这个校验和?

时间:2012-03-10 12:23:45

标签: checksum crc

我有一个警报系统,我已配置为将SMS消息发送到手机以及以太网。

以下是我收到的一些短信:

5522 18 1137 00 003 1C76
5522 18 3137 00 003 3278
5522 18 1130 00 002 E36E
5522 18 1401 00 001 ED6E
5522 18 1302 00 003 ED70
5522 18 1302 00 004 EE71
5522 18 1302 00 009 F376
5522 18 3147 00 009 417F
5522 18 1137 00 004 1D77
5522 18 3137 00 009 3379
5522 18 1602 00 000 0870

前4个字节是帐号,后2个是18,后4个是事件代码,2个组字节和3个区号。最后有4个字节,我怀疑是某种校验和。

这是某种Ademco Contact ID格式。但是,我不承认校验和。 它不是时间戳,因为最后一条消息(0870)是定期发送的,并且始终是相同的。

当通过DTMF发送时,0的值应为10,但我不知道是否是SMSes的情况。很可能不是。

4 个答案:

答案 0 :(得分:0)

#ACCT MT QXYZ GG CCC其中:

  • ACCT:4位数帐号(0-9,B-F)

  • MT:消息类型 -​​ 始终为18

  • Q:事件限定符,提供特定的事件信息:

    • 1:新活动或开幕

    • 3:新的恢复或关闭

    • 6:先前报告的情况仍然存在(状态报告)

  • XYZ:事件代码(3个十六进制数字0-9,B-F)

  • GG:组或分区编号(2个十六进制数字0-9,B-F)。使用00表示不适用特定的组或分区信息。

  • CCC:区号(事件报告)或用户(打开/关闭报告)(3个Hexdigits 0-9,B-F)。使用000表示不适用特定区域或用户信息。

要查找事件代码,请参阅this document(pdf)。

答案 1 :(得分:0)

Ademco联系人ID中的校验和公式使用以下公式计算:

S = HEX校验和是一位数。

(所有消息数字的总和+ S)MOD 15 = 0

如果该值等于10,则校验和数字为0。 官方联系ID规范如下:http://li0r.files.wordpress.com/2012/07/sia-dc-05-1999-09_contact_id.pdf

因此,以5522 18 1602 00 000 0870为例:

LET C = checksum

5+5+2+2+1+8+1+6+2=32

(32+S) modulo 15 is congruent to 0

然后我们需要15的最接近的倍数高于32,这将是45。

45-32=13

让我们测试一下。

45 modulo 15 is congruent to 0

但是,正确的是,由于联系人ID是16位数而您有19位,我怀疑您的面板使用的是Contact ID的其他专有实现。如果您发布来自我的面板的品牌/型号,我可以进一步解释。

我希望这能回答你的问题!

-Alex

P.S。:计算mod使用Google中的百分号 P.P.S:描述Contact ID的文件实际上是:DC-05-1999.09您引用的文件实际上是计算机接口通信协议规范。

答案 2 :(得分:0)

我只是想纠正AdemcoGuy的计算,因为它看似不正确: 所以,这个例子是 5522 18 1602 00 000 0870 我们需要将每个0替换为10。 所以: 5 + 5 + 2 + 2 + 1 + 8 + 1 + 6 + 10 + 2 + 10 + 10 + 10 + 10 + 10 = 92

比100-92 = 8

所以cheksum是8

无论如何,问题中的校验和似乎缺失了,最后4位数只知道是谁制造了已发送的面板:)

答案 3 :(得分:0)

我在试图找出我自己的警报系统 (Woonveilig/Egardia) 的校验和时遇到了这篇文章,该系统似乎使用了相同的格式。我找到了一个 forum post on the german alarm forum,其中包含一段 C 代码来计算 LUPUS 警报系统的 CRC。这种 CRC 计算方法似乎与我自己的和 Lasse 的基于 SMS 的系统相匹配。这是转换为简单计算工具的 C 代码:

#include <stdio.h>
#include <string.h>

// Code from: https://www.alarmforum.de/showthread.php?tid=12037&pid=75893

/**
* Fletcher Checksum.(LUPUS version, 16-bit)
*/
static unsigned int fletcher_sum(char* data, int len) {
    unsigned int sum1 = 0x0, sum2 = 0x0;
    while (len) {
        unsigned int tlen = (len > 256) ? 256 : len;
        len -= tlen;
        do {
            sum1 += *data++;
            sum1 = (sum1 & 0xff);
            sum2 += sum1;
            sum2 = (sum2 & 0xff);
        } while (--tlen);
    }
    return sum2 << 8 | sum1;
}

int main() {
    char input[50];
    int sum;
    printf("Enter input: ");
    fgets(input, sizeof(input), stdin);
    sum = fletcher_sum(input, strlen(input)-1);
    printf("%x\n", sum);
    return 0;
}

示例(问题帖子中的第一条短信):

# cc checksum.c
# ./a.out
Enter input: 5522 18 1137 00 003
1c76
相关问题