Advertisement
starlitepony

Bionicle Password Checking

Sep 24th, 2022
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. checksum_storage = [0, 0, 0, 0, 0, 0]
  2. password_char_codes = [0, 0, 0, 0, 0, 0]
  3.  
  4. valid_chars = ['B', 'C', 'D', 'F', 'G', 'H', 'J', 'K',
  5. 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
  6. 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4',
  7. '5', '7', '8', '9', '+', '$', '%', '#']
  8.  
  9. # Completed levels are stored in a bitwise method: 17 in binary is 0b00010001
  10. # The first and fifth bits are on, so 17 means the player has completed Lewa and Kopaka's levels
  11. toa_names = ['Lewa', 'Pohatu', 'Kopaka', 'Onua', 'Gali', 'Tahu', 'Takanuva']
  12.  
  13.  
  14. def init_password_char_codes(password):
  15. invalid_chars = [ch for ch in password if ch not in valid_chars]
  16. if invalid_chars:
  17. raise Exception
  18. password_char_codes[0] = valid_chars.index(password[0])
  19. password_char_codes[1] = valid_chars.index(password[1])
  20. password_char_codes[2] = valid_chars.index(password[2])
  21. password_char_codes[3] = valid_chars.index(password[3])
  22. password_char_codes[4] = valid_chars.index(password[4])
  23. password_char_codes[5] = valid_chars.index(password[5])
  24.  
  25.  
  26. def init_checksum_storage():
  27. checksum_storage[0] = 25 - password_char_codes[0] # Magic number - no idea why 25 is used specifically on the first char
  28. checksum_storage[1] = 0
  29. checksum_storage[2] = 0
  30. checksum_storage[3] = 0
  31. checksum_storage[4] = 0
  32. checksum_storage[5] = 0
  33.  
  34.  
  35. def get_checksum_step_1():
  36. for idx in range(1, 6):
  37. for idx2 in range(5):
  38. r3 = password_char_codes[idx]
  39. r3 = r3 // (2 ** idx2)
  40. r1 = idx
  41. if r3 % 2 != 0:
  42. r3 = checksum_storage[0] + idx2
  43. while r3 > 4:
  44. r1 = (r1 % 5) + 1
  45. r3 -= 5
  46. r3 = 2 ** r3
  47. checksum_storage[r1] = (r3 | checksum_storage[r1])
  48.  
  49.  
  50. def overwrite_password_char_codes():
  51. for i in range(1, 6):
  52. password_char_codes[i] = checksum_storage[i]
  53.  
  54.  
  55. def build_completed_level_string(byte_values, allow_takanuva=False):
  56. completed_levels = []
  57. binary_string = bin(byte_values)
  58. for idx, bit in enumerate(binary_string[::-1]):
  59. if bit == '1' and idx < len(toa_names):
  60. if toa_names[idx] == 'Takanuva' and not allow_takanuva:
  61. continue
  62. completed_levels.append(toa_names[idx])
  63. return ', '.join(completed_levels) if completed_levels else '-'
  64.  
  65.  
  66. def set_completed_levels():
  67. checksum_byte = 0
  68. for i in range(5):
  69. for subloop in range(5):
  70. r3 = password_char_codes[i]
  71. r3 = r3 // (2 ** subloop)
  72. if r3 & 1:
  73. checksum_byte += 1
  74. print(f'>> checksum: {str(checksum_byte)} char code: {password_char_codes[-1]}')
  75. if checksum_byte != password_char_codes[-1]:
  76. print('Invalid checksum, clearing password')
  77. clear_password()
  78. return
  79. r0 = password_char_codes[2]
  80. r1 = password_char_codes[3]
  81. r3 = 3 & r1 # 3 and 15 = 3
  82. r4 = 3 & r0 # 3 and 15 = 3
  83. r4 = (r3 * 4) | r4 # 12 | 3 = 15
  84. r5 = password_char_codes[4]
  85. r0 = r0 & 12 # 15 and 12 = 12
  86. r1 = r1 & 12 # 15 and 12 = 12
  87. r2 = 3 & r5 # 3 and 15 = 3
  88. r3 = 12 & r5 # 12 and 15 = 12
  89. r2 *= 16 # 3 * 16 = 48
  90. r0 = (r0 // 4) | r1 # 3 | 12 = 15
  91. r3 = r3 * 4 # 12 * 4 = 48
  92. r4 = r4 | r2 # 15 | 48 = 63
  93. r0 = r0 | r3 # 15 | 48 = 63
  94. toa_status = r4
  95. nuva_status = r0
  96. print(r4)
  97. print(r0)
  98. print(f'Toa: {build_completed_level_string(r4, False)}')
  99. print(f'Nuva: {build_completed_level_string(r0, False)}')
  100. if nuva_status == 0 or toa_status == 63:
  101. clear_password()
  102. else:
  103. print('Illegal checksum state - cannot have any nuva status without completed toa status')
  104.  
  105.  
  106. def clear_password():
  107. for idx in range(len(password_char_codes)):
  108. password_char_codes[idx] = 0
  109.  
  110.  
  111. def input_password(*args):
  112. init_password_char_codes(*args)
  113. init_checksum_storage()
  114. get_checksum_step_1()
  115. print(checksum_storage)
  116. print(password_char_codes)
  117. print("---")
  118. overwrite_password_char_codes()
  119. print(checksum_storage)
  120. print(password_char_codes)
  121. set_completed_levels()
  122.  
  123.  
  124. if __name__ == '__main__':
  125. # input_password('BBBBBB')
  126. # input_password('WWWWWW')
  127. # input_password('3QQQGC')
  128. input_password('J+B%%%')
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement