Skip to content

Instantly share code, notes, and snippets.

@bbayles
Last active January 3, 2023 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbayles/fe11d5c86bcf2af2e824db8b80626ed0 to your computer and use it in GitHub Desktop.
Save bbayles/fe11d5c86bcf2af2e824db8b80626ed0 to your computer and use it in GitHub Desktop.
Burning Rangers password functions
ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456'
XOR_CONSTANT = 0x9fd43b75
def from_binary(all_bits):
# Given a string of 50 '0' and '1' characters, return a 10 character password string
ret = []
for i in range(5, len(all_bits) + 1, 5):
j = int(all_bits[i - 5:i], 2)
ret.append(ALPHABET[j])
return ''.join(ret)
def get_checksum(n):
# Given the an integer representing the lower 32 bits of the decoded password,
# return a 16 bit integer representing the password's checksum.
# This is an implementation of CRC-16-GENIBUS
msb_mask = 0x00008000
xor_constant = 0x1021
n_bytes = n.to_bytes(4, 'big')
ret = 0xffff
for i in range(4):
ret ^= ((n_bytes[i] & 0xff) << 8)
for j in range(2):
if ((msb_mask & ret & 0xffff) == 0):
x = ret << 1
else:
x = (ret & 0xffff) << 1 ^ xor_constant
if ((msb_mask & x & 0xffff) == 0):
x <<= 1
else:
x = (x & 0xffff) << 1 ^ xor_constant
if ((msb_mask & x & 0xffff) == 0):
x <<= 1
else:
x = (x & 0xffff) << 1 ^ xor_constant
if ((msb_mask & x & 0xffff) == 0):
ret = x << 1
else:
ret = ((x & 0xffff) << 1 ^ xor_constant)
return ~ret & 0xffff
def construct_password(mission, n_15, n_12):
# Given a mission number (1, 2, or 3), a 15 bit integer, and a 12 bit integer,
# return a valid password string. The meaning of the two integers is currently
# unknown. However:
# construct_password(1, 0, 0) gives D2H5P4IO2V, the original map for mission 1.
# construct_password(2, 0, 0) gives DYJSP4IK2V, the original map for mission 2.
# construct_password(3, 0, 0) gives D42GP4IG2V, the original map for mission 3.
if not (1 <= mission <= 3):
raise ValueError('invalid mission')
if not (0 <= n_15 < 2 ** 15):
raise ValueError('invalid n_15')
if not (0 <= n_12 < 2 ** 12):
raise ValueError('invalid n_12')
lower_bits = (
format(n_15, '018b') + format(mission - 1, '02b') + format(n_12, '012b')
)
lower_int = int(lower_bits, 2)
checksum_int = get_checksum(lower_int)
checksum_bits = format(checksum_int, '016b')
reconstructed_bits = '00' + checksum_bits + format(lower_int ^ XOR_CONSTANT, '032b')
return from_binary(reconstructed_bits)
@bbayles
Copy link
Author

bbayles commented Jan 3, 2023

Here's a more straightforward implementation of the checksum function.

def crc_16_genibus(n):
     ret = 0xffff
     for d in n.to_bytes(4, 'big'):
         x = (ret >> 8) ^ d
         x ^= (x >> 4)
         ret = (ret << 8) ^ (x << 12) ^ (x << 5) ^ x
         ret &= 0xffff
     return ret ^ 0xffff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment