From a30ce986072011fcccacb9fb4356b5db85ad3bb1 Mon Sep 17 00:00:00 2001 From: Markus Birth Date: Mon, 24 Feb 2020 14:05:09 +0100 Subject: [PATCH] Update checksum calculation and make it work for B and C codes. --- ninty-codes.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ninty-codes.py b/ninty-codes.py index 4434c0e..cb17967 100755 --- a/ninty-codes.py +++ b/ninty-codes.py @@ -112,11 +112,11 @@ def safe2real(code: str): code = code.replace('Y', 'O') # O might be confused with 0 return code -def generateChecksum(base_code): +def generateChecksum(base_code, base = 30): if len(base_code) != 15: raise RuntimeError("Bad argument to checksum") - # Mystery/bug: Why is this ord('7') in particular? 55, 0o55 and 0x55 are all unrelated to anything in base 33. The check looks like it's trying to do c - 'A', but does the weirdest thing instead. - cksum = reduce(lambda cksum, c: (cksum + (ord(c) - ord('0') if ord(c) <= ord('9') else ord(c) - ord('7'))) % 33, base_code, 0) + # https://www.reddit.com/r/SwitchHacks/comments/f7psrk/anatomy_of_an_eshop_card_code/fijt5d4/ + cksum = sum(int(c, base) for c in base_code) % base return CHARSET[cksum] def validate(code): @@ -124,7 +124,9 @@ def validate(code): # Make uppercase if necessary, then change X and Y back to their base 33 equivalents unmangled_code = safe2real(code) theirs = unmangled_code[15] - mine = generateChecksum(unmangled_code[0:15]) + code_type = get_type(code) + base = 33 if code_type == '_A_' else 30 + mine = generateChecksum(unmangled_code[0:15], base) return theirs == mine def parse(code): @@ -173,7 +175,7 @@ if __name__ == '__main__': seen_chars[code_type] = set() for c in s[1:]: seen_chars[code_type].add(c) - if code_type == '_A_': + if code_type != 'NUM': valid = validate(s) print('{} {}'.format(s, "☑ " if valid else "☒ "), end='') if not valid: