I cant verify seed generation if someone can see what is wrong

Question:

So i got this function that generates seeds makeseed() and now im trying to make a "verify" seed keep in mind that any seed generated IS Correct so i want it so that the user can input seeds and it’ll check if its valid or not.

here is my code

import random

def getchecksum(seed):
    checksum = 0
    while True:
        checksum = (checksum + (seed & 0xFF)) & 0xFF
        checksum = (2 * checksum + (checksum >> 7)) & 0xFF
        seed >>= 5
        if seed == 0:
            break
    return checksum

def makeseed():
    seed = random.randint(1, 4294967295)
    checksum = getchecksum(seed)
    abc = "ABCDEFGHJKLMNPQRSTWXYZ01234V6789"
    seedsprev = ((seed ^ 0xFEF7FFD) << 8) | checksum
    finalseed = ""
    for loopindex in range(0, 8):
        finalseed = abc[seedsprev & 0x1F] + finalseed
        seedsprev >>= 5
    return finalseed

def is_valid_seed(seed):
    """
    Checks if a seed is valid.

    Args:
        seed: The seed to check.

    Returns:
        True if the seed is valid, False otherwise.
    """
    seed_length = len(seed)
    if seed_length != 8:
        return False

    abc = "ABCDEFGHJKLMNPQRSTWXYZ01234V6789"

    try:
        seed_int = 0
        for i in range(7, -1, -1):
            seed_int <<= 5
            seed_int |= abc.index(seed[i])

        checksum = getchecksum(seed_int)
        seed_int = ((seed_int ^ 0xFEF7FFD) << 8) | checksum

        final_seed = ""
        for _ in range(8):
            final_seed = abc[seed_int & 0x1F] + final_seed
            seed_int >>= 5

        return final_seed == seed
    except ValueError:
        return False

ok = makeseed()
print(is_valid_seed(ok)) #to check if the function is correct
print(ok)

I tried to reverse what the makeseed did and i was expecting it to work but it didnt

Asked By: jutyve

||

Answers:

Your string encode/decode was bad because you reassembled the digits in reverse order. The best way to test for something like that is to split out the encode and decode to separate functions so you can run a unit test like decode(encode(x)) == x. I probably would have used an existing library like base32, base64 or just hexadecimal.

Your reversal of the checksum operations also didn’t actually reverse the operations. It just did some of the same math in the same order, not the reverse order.

The thing you need to check in is_valid_seed is whether the checksum actually checks out.

MY_ALPHABET = "ABCDEFGHJKLMNPQRSTWXYZ01234V6789"

def encode(seed: int) -> str:
    encoded = ""
    for _ in range(0, 8):
        value = seed & 0x1F
        seed >>= 5
        encoded = MY_ALPHABET[value] + encoded
    return encoded


def decode(encoded: bytes) -> int:
    seed = 0
    for digit in encoded:
        value = MY_ALPHABET.index(digit)
        seed <<= 5
        seed += value
    return seed


assert(99999 == decode(encode(99999)))


def getchecksum(seed: int):
    checksum = 0
    while True:
        checksum = (checksum + (seed & 0xFF)) & 0xFF
        checksum = (2 * checksum + (checksum >> 7)) & 0xFF
        seed >>= 5
        if seed == 0:
            break
    return checksum


def make_seed(seed: int):
    checksum = getchecksum(seed)
    seedsprev = ((seed ^ 0xFEF7FFD) << 8) | checksum
    return encode(seedsprev)


def is_valid_seed(encoded: str):
    seed = decode(encoded)
    checksum = seed & 0xff
    original_seed = (seed >> 8) ^ 0xFEF7FFD
    return checksum == getchecksum(original_seed)


assert is_valid_seed(make_seed(7777))
assert not is_valid_seed('ABCDEFGH')
Answered By: Kenny Ostrom