Pokémon data structure (Generation IV): Difference between revisions

From Bulbapedia, the community-driven Pokémon encyclopedia.
Jump to navigationJump to search
(Added information on the checksum and encryption algorithms; minor edits to layout and top-matter for clarity.)
(Prettified layout, corrected style, changed wording.)
Line 1: Line 1:
Boxed Pokémon in the games [[Pokémon Diamond and Pearl|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.
Boxed Pokémon in the games [[Pokémon Diamond and Pearl|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 ==
== Checksum ==
Line 8: Line 8:


The checksum is calculated in three steps:
The checksum is calculated in three steps:
# Split the unencrypted data from 0x08..0x87 into two-byte words,
# Split the unencrypted data from offsets 0x08 to 0x87 into two-byte words,
# Take the sum of the words, and
# Take the sum of the words, and
# Truncate the sum to sixteen bits.
# Truncate the sum to sixteen bits.
Line 14: Line 14:
== Block Shuffling ==
== 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:
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]].  Give the personality value ''pv'', the expression yielding the shift value is:
: ''((pv >> 0xD) & 0x1F) % 24''
: ''((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:
To shuffle the blocks, take the four blocks of unencrypted data to be ''A'', ''B'', ''C'', and ''D''.  The blocks shall be rearranged in the encrypted data according to this table:


{|
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
| 00 = ABCD
|- style="background: #ccc;" align="center"
| 01 = ABDC
! Shift Value
| 02 = ACBD
! Block Order
| 03 = ACDB
|- style="background: #eee;" align="center"
| 04 = ADBC
| 00
| 05 = ADCB
| ABCD
|-
|- style="background: #ddd;" align="center"
| 06 = BACD
| 01
| 07 = BADC
| ABDC
| 08 = BCAD
|- style="background: #eee;" align="center"
| 09 = BCDA
| 02
| 10 = BDAC
| ACBD
| 11 = BDCA
|- style="background: #ddd;" align="center"
|-
| 03
| 12 = CABD
| ACDB
| 13 = CADB
|- style="background: #eee;" align="center"
| 14 = CBAD
| 04
| 15 = CBDA
| ADBC
| 16 = CDAB
|- style="background: #ddd;" align="center"
| 17 = CDBA
| 05
|-
| ADCB
| 18 = DABC
|- style="background: #eee;" align="center"
| 19 = DACB
| 06
| 20 = DBAC
| BACD
| 21 = DBCA
|- style="background: #ddd;" align="center"
| 22 = DCAB
| 07
| 23 = DCBA
| BADC
|- style="background: #eee;" align="center"
| 08
| BCAD
|- style="background: #ddd;" align="center"
| 09
| BCDA
|- style="background: #eee;" align="center"
| 10
| BDAC
|- style="background: #ddd;" align="center"
| 11
| BDCA
|- style="background: #eee;" align="center"
| 12
| CABD
|- style="background: #ddd;" align="center"
| 13
| CADB
|- style="background: #eee;" align="center"
| 14
| CBAD
|- style="background: #ddd;" align="center"
| 15
| CBDA
|- style="background: #eee;" align="center"
| 16
| CDAB
|- style="background: #ddd;" align="center"
| 17
| CDBA
|- style="background: #eee;" align="center"
| 18
| DABC
|- style="background: #ddd;" align="center"
| 19
| DACB
|- style="background: #eee;" align="center"
| 20
| DBAC
|- style="background: #ddd;" align="center"
| 21
| DBCA
|- style="background: #eee;" align="center"
| 22
| DCAB
|- style="background: #ddd;" align="center"
| 23
| DCBA
|}
|}


== Encryption ==
== 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:
The encryption uses the pseudorandom number generator (PRNG), a linear congruential generator.  Elements of the PRNG can be described with the recursive function:
: ''X[n+1] = (0x41C64E6D * X[n] + 0x6073) % 0xFFFFFFFF''
: ''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:
To decrypt the data, given a function ''rand()'' which returns the result of the above given function:
# Seed the PRNG with the checksum,
# Seed the PRNG with the checksum (let ''X[n]'' be the checksum),
# Sequentially, for each 2-byte word ''Y'' from 0x08 to 0x87, apply the transformation: ''unencryptedByte = Y xor rand()''
# 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.
# Un-shuffle the blocks using the block shuffling algorithm above.

Revision as of 08:43, 12 July 2008

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:

  1. It validates the data after decryption, and
  2. It serves as the encryption key for the data.

The checksum is calculated in three steps:

  1. Split the unencrypted data from offsets 0x08 to 0x87 into two-byte words,
  2. Take the sum of the words, and
  3. 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. Give the personality value pv, the expression yielding the shift value is:

((pv >> 0xD) & 0x1F) % 24

To shuffle the blocks, take the four blocks of unencrypted data to be A, B, C, and D. The blocks shall be rearranged in the encrypted data according to this table:

Shift Value Block Order
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 uses the pseudorandom number generator (PRNG), 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:

  1. Seed the PRNG with the checksum (let X[n] be the checksum),
  2. Sequentially, for each 2-byte word Y from 0x08 to 0x87, apply the transformation: unencryptedByte = Y xor rand()
  3. Un-shuffle the blocks using the block shuffling algorithm above.

Unencrypted bytes

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