Mii: Difference between revisions
→Mii format: System ID has been proven 8 bit |
Add checksum section: explain the checksum algorithm using pseudo code. |
||
Line 38: | Line 38: | ||
| 0xC81E | | 0xC81E | ||
| 0x2 | | 0x2 | ||
| Checksum of all of the above. | | Checksum of all of the above (the first 0xC81E byte). See section [[#Checksum|below]]. | ||
|- | |- | ||
| 0xC820 | | 0xC820 | ||
Line 75: | Line 75: | ||
Alternative interpretation: FFFF FFFF 0000 0000 0000 0000 0000 is the 1st item; FF7F FF7F 0000 [...] the 2nd, etc; | Alternative interpretation: FFFF FFFF 0000 0000 0000 0000 0000 is the 1st item; FF7F FF7F 0000 [...] the 2nd, etc; | ||
==Checksum== | |||
The algorithm used to verify the integrity of the database is based on [http://srecord.sourceforge.net/crc16-ccitt.html CRC16-CCITT], though it's an incorrect implementation. It is the same algorithm used to verify [http://wiibrew.org/wiki/Mii_Data#Block_format Mii Data on the Wii]. | |||
To obtain the correct value for the checksum, apply the algorithm to the first 0xC81E bytes of the database. This can be done using [https://www.dropbox.com/s/863idp5wmh50c1v/Gold_Mii_Tools.zip?dl=0 FixCRC for Windows]; alternativly a pseudocode implementation of the checksum algorithm is given below: | |||
<source lang="python"> | |||
def crc16_CCITTWii(u8[]: data) -> u16: | |||
"""Calculate a checksum of data using the CRC16-CCITT implementation of the Wii | |||
This implementation uses 0x0000 as the starting value, which is different | |||
from what CRC16-CCITT specifies. | |||
""" | |||
# note: a correct implementation of CRC16-CCITT | |||
# would initialize this to 0xffff | |||
u32 crc := 0x0 | |||
for byte in data: | |||
# Iterate over every of the 8 bits in byte. | |||
# Begin with the most significant bit. (7, 6, ... , 1, 0) | |||
for bit in 7..0: | |||
# & - binary `and'; <</>> - bitshift left/right; ^ - binary `xor' | |||
crc := ( | |||
(crc << 1) | ((byte >> bit) & 0x1) | |||
^ (0x1021 if crc & 0x8000 else 0) | |||
) | |||
for _ in 0..15: | |||
crc := (crc << 1) ^ (0x1021 if crc & 0x8000 else 0) | |||
# only return the lowest 16 bit of crc | |||
return (u16) (crc & 0xffff) | |||
checksum := crc16_CCITTWii(miidb[0:0xc81e]) # checksum over the first 0xc81e bytes | |||
</source> | |||
==Mii format== | ==Mii format== |