Python:异或字符串中的每个字符
Python: XOR each character in a string
我正在尝试验证字符串的校验和,在本例中,它是通过对每个单独的字符执行 XOR 计算得出的。
给定我的测试字符串:
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-8
和 ascii
中尝试了 encoding/decoding,但我不确定文本应该使用什么编码,两者的结果相同。
我在 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;
我创建了 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 代码中得到的假设是不正确的。
正如@metatoaster、@XD573 和评论中的其他一些人帮助弄清楚的那样,问题是结果(以 10 为底)与我想要的解决方案(以 16 为底)之间的差异。
代码的结果 40
是正确的 - 在基数 10 中,但是我试图实现的正确值 28
是在基数 16 中给出的。只需将解决方案从基数转换16 以 10 为基数,例如:
int('28', 16)
我得到40
,计算结果。
#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)
我正在尝试验证字符串的校验和,在本例中,它是通过对每个单独的字符执行 XOR 计算得出的。
给定我的测试字符串:
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-8
和 ascii
中尝试了 encoding/decoding,但我不确定文本应该使用什么编码,两者的结果相同。
我在 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;
我创建了 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 代码中得到的假设是不正确的。
正如@metatoaster、@XD573 和评论中的其他一些人帮助弄清楚的那样,问题是结果(以 10 为底)与我想要的解决方案(以 16 为底)之间的差异。
代码的结果 40
是正确的 - 在基数 10 中,但是我试图实现的正确值 28
是在基数 16 中给出的。只需将解决方案从基数转换16 以 10 为基数,例如:
int('28', 16)
我得到40
,计算结果。
#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)