Python:对字符串中的每个字符进行异或操作

3
我将尝试验证一个字符串的校验和,这个字符串是通过对每个单独字符执行异或运算计算得出的。以下是测试字符串:
check_against = "GPGLL,5300.97914,N,00259.98174,E,125926,A"

我想这应该很简单:

result = 0
for char in check_against:
    result = result ^ ord(char)

我知道结果应该是28,但我的代码却给出了40
我不确定文本应该使用哪种编码,虽然我尝试过使用utf-8ascii进行编码/解码,但结果相同。
我在C中实现了相同的算法,只需对char数组进行XOR即可得到完美的结果,那我错过了什么?
编辑
所以,我实现(我认为)在C中也是同样的事情已经有一段时间了。我知道它是在一个Objective-C项目中,但我认为我只是这样做了。完全错误,首先有一步,我将最后的校验和字符串值转换为十六进制,如下所示(我在这里填写了一些内容,以便只粘贴相关的内容):
 unsigned int checksum = 0;
 NSScanner *scanner = [NSScanner scannerWithString:@"26"];
 [scanner scanHexInt:&checksum];

然后我按照以下步骤计算校验和:

 NSString sumString = @"GPGLL,5300.97914,N,00259.98174,E,125926,A";
 unsigned int sum = 0;
 for (int i=0;i<sumString.length;i++) {
     sum = sum ^ [sumString characterAtIndex:i];
 }

然后,我将进行如下比较:
 return sum == checksum;

3
另一种检查原始值的方法是使用 map(ord, check_against),然后使用operator.xor进行缩减,像这样 reduce(xor, map(ord, check_against))。在Python 3中,它将变为 functools.reduce - metatoaster
1
我认为对于你给出的字符串示例,utf-8ascii是死胡同,因为ASCII字符在Unicode中具有相同的值。在Python 2中,bytearray(check_against, encoding='utf-8') == bytearray(check_against)返回True - chucksmash
2
还有,最后,你的C代码是什么?我确定答案是10进制下的40和16进制下的0x28。你是如何用C生成输出28的? - metatoaster
1
我刚刚将你的Python代码直接移植到C,并验证结果正确为40。链接:https://ideone.com/YK8FOp - Daniel Pryden
5
最后注意事项,似乎没有人注意到:printf("%x\n", 40); 的结果是打印出 28 - metatoaster
显示剩余2条评论
3个回答

2
因为 @metatoaster, @XD573 和评论区的其他人帮忙解决了这个问题,问题在于结果是十进制的,而我的期望解决方案是十六进制的。
代码的结果40是正确的 - 在十进制中,然而我想要的正确值 28 是以十六进制给出的。只需将解决方案从十六进制转换为十进制,例如:
int('28', 16)

我得到了40,这是计算出的结果。


2
#python3
str = "GPGLL,5300.97914,N,00259.98174,E,125926,A"
cks = 0
i = 0

while(i<len(str)):
    cks^=ord(str[i])
    i+=1

print("hex:",hex(cks))
print("dec:",cks)

1
我创建了如下所示的C语言版本:

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

int main()
{
    char* str1="GPGLL,5300.97914,N,00259.98174,E,125926,A";
    int sum = 0;
    int i = 0;

    for (i; i < strlen(str1); i++) {
        sum ^= str1[i];
    }

    printf("checksum: %d\n", sum);

    return 0;
}

当我编译并运行它时:

$ gcc -o mytest mytest.c
$ ./mytest
checksum: 40

这让我相信,你从等价的C代码中得出的假设是不正确的。

你说得对,我刚刚添加了我的(Objective C,忘记它不仅仅是C)代码的编辑。我目前的代码似乎缺少将校验和转换为十六进制字符串的部分。此外,我认为在数字的十六进制值和字符串值之间存在一些混淆,包括我自己在内。 - Flynn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接