简体   繁体   中英

Python: XOR each character in a string

I'm trying to validate a checksum on a string which in this case is calculated by performing an XOR on each of the individual characters.

Given my test string:

check_against = "GPGLL,5300.97914,N,00259.98174,E,125926,A"

I figured it would be as simple as:

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

I know the result should be 28 , however my code gives 40 .

I'm not sure what encoding the text is suppose to be in, although I've tried encoding/decoding in utf-8 and ascii , both with the same result.

I implemented this same algorithm in C by simply doing an XOR over the char array with perfect results, so what am I missing?

Edit

So it was a little while ago that I implemented (what I thought) was the same thing in C. I knew it was in an Objective-C project but I thought I had just done it this way. Totally wrong, first there was a step where I converted the checksum string value at the end to hex like so (I'm filling some things in here so that I'm only pasting what is relevant):

 unsigned int checksum = 0;
 NSScanner *scanner = [NSScanner scannerWithString:@"26"];
 [scanner scanHexInt:&checksum];

Then I did the following to compute the 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];
 }

Then I would just compare like so:

 return sum == checksum;

So as @metatoaster, @XD573, and some others in the comments have helped figure out, the issue was the difference between the result, which was base 10, and my desired solution (in base 16).

The result for the code, 40 is correct - in base 10, however my correct value I was trying to achieve, 28 is given in base 16. Simply converting the solution from base 16 to base 10, for example like so:

int('28', 16)

I get 40 , the computed result.

#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)

I created the C version as shown here:

#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;
}

And When I compiled and ran it:

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

Which leads me to believe that the assumptions you have from your equivalent C code are incorrect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM