我正在尝试移植一个计算GPS校验和到Python的C函数。根据接收端,我有时会错误地计算校验和,因此必须在那里有一个错误。
C代码是
void ComputeAsciiChecksum(unsigned char *data, unsigned int len,
unsigned char *p1, unsigned char *p2)
{
unsigned char c,h,l;
assert(Stack_Low());
c = 0;
while (len--) {
c ^= *data++;
}
h = (c>>4);
l = c & 0xf;
h += '0';
if (h > '9') {
h += 'A'-'9'-1;
}
l += '0';
if (l > '9') {
l += 'A'-'9'-1;
}
*p1 = h;
*p2 = l;
}
我对Python函数的尝试是
def calcChecksum(line):
c = 0
i = 0
while i < len(line):
c ^= ord(line[i]) % 256
i += 1
return '%02X' % c;
答案 0 :(得分:4)
以下是设置测试环境以诊断问题的方法。
将上述C函数复制到文件中,删除assert()
行,并使用
gcc -shared -o checksum.so checksum.c
(如果您使用的是Windows或其他任何内容,请执行上述操作。)
将此代码复制到Python文件:
import ctypes
import random
c = ctypes.CDLL("./checksum.so")
c.ComputeAsciiChecksum.rettype = None
c.ComputeAsciiChecksum.argtypes = [ctypes.c_char_p, ctypes.c_uint,
ctypes.c_char_p, ctypes.c_char_p]
def compute_ascii_checksum_c(line):
p1 = ctypes.create_string_buffer(1)
p2 = ctypes.create_string_buffer(1)
c.ComputeAsciiChecksum(line, len(line), p1, p2)
return p1.value + p2.value
def compute_ascii_checksum_py(line):
c = 0
i = 0
while i < len(line):
c ^= ord(line[i]) % 256
i += 1
return '%02X' % c;
现在您可以访问校验和功能的两个版本,并可以比较结果。我无法找到任何差异。
(顺便说一下,你如何计算C中字符串的长度?如果你使用strlen()
,这将停止在NUL字节。)
作为旁注,你的Python版本并不是真正的惯用Python。这里有两个更惯用的版本:
def compute_ascii_checksum_py(line):
checksum = 0
for c in line:
checksum ^= ord(c)
return "%02X" % checksum
或
def compute_ascii_checksum_py(line):
return "%02X" % reduce(operator.xor, map(ord, line))
请注意,这些实现应与您的实现完全相同。
答案 1 :(得分:0)
你签出了this cookbook recipe吗?它暗示您应该在“line”中包含哪些输入,在校验和前面返回一个星号,并提供一个(输入,输出)数据对,您可以将其用作测试数据。
你确定“接收器”工作正常吗?问题是由大写和小写的十六进制字母引起的吗?
答案 2 :(得分:-3)