Mii: Difference between revisions

Ryccardo (talk | contribs)
Mii format: System ID has been proven 8 bit
Phijor (talk | contribs)
Add checksum section: explain the checksum algorithm using pseudo code.
Line 38: Line 38:
| 0xC81E
| 0xC81E
| 0x2
| 0x2
| Checksum of all of the above. Can be calculated with [https://www.dropbox.com/s/863idp5wmh50c1v/Gold_Mii_Tools.zip?dl=0 FixCRC for Windows].
| 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==