Pokémon data structure (Generation IV)
Boxed Pokémon in the games Diamond and Pearl are stored in a 136-byte structure. All unencrypted values are stored in little-endian format. The game encrypts the data when it is stored into save data. In-party pokémon have additional values appended to them to hold calculated stats. The information below describes the boxed pokémon data format.
Checksum
The checksum serves two purposes:
- It validates the data after decryption, and
- It serves as the encryption key for the data.
The checksum is calculated in three steps:
- Split the unencrypted data from 0x08..0x87 into two-byte words,
- Take the sum of the words, and
- Truncate the sum to sixteen bits.
Block Shuffling
The 128 bytes of pokémon data are split into four 32-byte blocks for shuffling. The blocks are shuffled according to a shift value derived from the Personality value. The expression yielding the shift value is:
- ((pv >> 0xD) & 0x1F) % 24
Take the four blocks of unencrypted data to be A, B, C, and D. The blocks shall be shifted according to this table:
00 = ABCD | 01 = ABDC | 02 = ACBD | 03 = ACDB | 04 = ADBC | 05 = ADCB |
06 = BACD | 07 = BADC | 08 = BCAD | 09 = BCDA | 10 = BDAC | 11 = BDCA |
12 = CABD | 13 = CADB | 14 = CBAD | 15 = CBDA | 16 = CDAB | 17 = CDBA |
18 = DABC | 19 = DACB | 20 = DBAC | 21 = DBCA | 22 = DCAB | 23 = DCBA |
Encryption
The encryption is dependent upon the pseudorandom number generator (PRNG), which is in turn a linear congruential generator. Elements of the PRNG can be described with the recursive function:
- X[n+1] = (0x41C64E6D * X[n] + 0x6073) % 0xFFFFFFFF
To decrypt the data, given a function rand() which returns the result of the above given function:
- Seed the PRNG with the checksum,
- Sequentially, for each 2-byte word Y from 0x08 to 0x87, apply the transformation: unencryptedByte = Y xor rand()
- Un-shuffle the blocks using the block shuffling algorithm above.
Unencrypted bytes
- 00-03 Personality value
- 04-05 Unknown
- 06-07 Checksum
Block A
- 08-09 Species ID
- 0A-0B Held Item
- 0C-0D OT ID
- 0E-0F OT Secret ID
- 10-13 Experience points
- 14 Friendship/Egg Steps to Hatch
- 15 Ability
- 16 Markings
- 17 Country of Origin
- 18-1D Effort values
- 1E-23 Contest stats
- 24-27 Ribbons
Block B
- 28-2F Moveset
- 30-33 Move PP
- 34-37 Move PP Ups
- 38-3B Individual values
- 3C-3F Ribbons 2
- 40 Gender
- 41-47 Unknown
Block C
- 48-5D Nickname
- 5E Unknown
- 5F Hometown
- 60-62 Contests
- 63-67 Unknown
Block D
- 68-77 OT Name
- 78-7A Date Egg Received
- 7B-7D Date Met
- 7E-7F Egg Location
- 80-81 Met At Location
- 82 Pokérus
- 83 Poké Ball
- 84 Met At Level
- 85 Encounter Type
- 86-87 Unknown