I've started the work to decode the password system of MoG. I want that all the passwords working in the original MoG to work in the Remake, and viceversa.
I know it can be a difficult process and that can consume a lot of hours of my free time, but I think it worths the effort!! Notice that the news posted here is in reverse order (the oldest is the first one). This has been done so in order to facilitate the reading.
Last update: 21-07-2002
After saving various dozens of passwords, I noticed the code structure. This is the initial password:
UR3F UR3F UR4F 423R UR3F UR3F UR3F UR3F UR3F UR3F URS4 8
I think it can be divided into several groups:
UR3F UR3F UR4F 423R UR3F UR3F UR3F UR3F UR3F UR3F URS4 8
Where the colors mean:
I've started by the Checksum decoding. And after several tries, I found the formula to compute it. Each character has a numerical value. Contained in the following table:
0 | 1 | 6 | 7 | C | 13 | I | 19 | O | 25 | U | 31 |
1 | 2 | 7 | 8 | D | 14 | J | 20 | P | 26 | V | 32 |
2 | 3 | 8 | 9 | E | 15 | K | 21 | Q | 27 | W | 33 |
3 | 4 | 9 | 10 | F | 16 | L | 22 | R | 28 | X | 34 |
4 | 5 | A | 11 | G | 17 | M | 23 | S | 29 | Y | 35 |
5 | 6 | B | 12 | H | 18 | N | 24 | T | 30 | Z | 36 |
If we add the values of all the characters in a password (except those ones contained in the checksum group), we obtain a number. Now we just have to convert it to hexadecimal and the last two digits are the checksum code!!!
Let's see it working with the initial password:
UR3F UR3F UR4F 423R UR3F UR3F UR3F UR3F UR3F UR3F URS4 8
We add the values for each character:
31+28+4+16+ 31+28+4+16+ 31+28+5+16+ 5+3+4+28+ 31+28+4+16+ 31+28+4+16+ 31+28+4+16+ 31+28+4+16+ 31+28+4+16+ 31+28+4+16+ 31+28+29 = 840
Converting 840 to hexadecimal is 348. And if we take the last two digits: we have 48, whicht is exactly the checksum code!!! I've tried this with several codes and it worked for each one.
Well, nothing more for today, but with this information I think that I'll have no problem to decode the rest of character groups in the passwords for the next of may be the other remake release!!
Hi again, after saving even more dozens of passwords, I have decoded the information related to the nº of arrows, coins and keys. First of all, as each character of the password can take any out of 36 posible values, at much 5 bits of information can be stored (assuming that the information is stored in binary).
I've noticed also, that the digits of the nº of arrows, etc... are stored separately. What induces to think that they are stored in BCD (Binary Coded Decimal). As 4 bits are needed to store each digit in BCD, and 5 bits can be represented in each character we have not an exact mapping between digits and characters. The first thing that I've to find in order to validate my hypotheses is to find the bit mapping between the BCD digits and the password characters.
Let's introduce some notation.
To represent the bits for the three digits (hundreds, teens, and units) of the arrow counter we use:
ah1,ah2,ah3,ah4 - at1,at2,at3,at4 - au1,au2,au3,au4
For the coins we use:
ch1,ch2,ch3,ch4 - ct1,ct2,ct3,ct4 - cu1,cu2,cu3,cu4
And for the keys:
kh1,kh2,kh3,kh4 - kt1,kt2,kt3,kt4 - ku1,ku2,ku3,ku4
As each character can hold up to 5 bits, I found that the bits are mapped this way:
U | R | 3 | F | U | R | 3 | F | U | R |
---|---|---|---|---|---|---|---|---|---|
at1 at2 at3 at4 au1 |
au2 au3 au4 --- --- |
--- --- ah1 ah2 ah3 |
ah4 ct1 ct3 ct4 ct5 |
cu1 cu2 cu3 cu4 --- |
--- --- --- ch1 ch2 |
ch3 ch4 kt1 kt2 kt3 |
kt4 ku1 ku2 ku3 ku4 |
--- --- --- --- kh1 |
kh2 kh3 kh4 --- --- |
Now that we suppose where the bits are mapped. We have to see how we can obtain each character by knowing its bit values. Well, after saving about a hundred of codes in the emulator. I've created this table:
Position: | 1 2 3 4 | ||||
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | U R 3 F |
0 | 0 | 0 | 0 | 1 | 7 U R 3 |
0 | 0 | 0 | 1 | 0 | 2 7 U R |
0 | 0 | 0 | 1 | 1 | G 2 7 U |
0 | 0 | 1 | 0 | 0 | 4 G 2 7 |
0 | 0 | 1 | 0 | 1 | X 4 G 2 |
0 | 0 | 1 | 1 | 0 | 5 X 4 G |
0 | 0 | 1 | 1 | 1 | B 5 X 4 |
0 | 1 | 0 | 0 | 0 | K B 5 X |
0 | 1 | 0 | 0 | 1 | N K B 5 |
0 | 1 | 0 | 1 | 0 | 9 N K B |
0 | 1 | 0 | 1 | 1 | 0 (zero) 9 N K |
0 | 1 | 1 | 0 | 0 | P 0 9 N |
0 | 1 | 1 | 0 | 1 | Q P 0 9 |
0 | 1 | 1 | 1 | 0 | T Q P 0 |
0 | 1 | 1 | 1 | 1 | H T Q P |
1 | 0 | 0 | 0 | 0 | V H T Q |
1 | 0 | 0 | 0 | 1 | E V H T |
1 | 0 | 0 | 1 | 0 | 6 E V H |
1 | 0 | 0 | 1 | 1 | O 6 E V |
1 | 0 | 1 | 0 | 0 | M O 6 E |
1 | 0 | 1 | 0 | 1 | W M O 6 |
1 | 0 | 1 | 1 | 0 | A W M O |
1 | 0 | 1 | 1 | 1 | J A W M |
1 | 1 | 0 | 0 | 0 | 1 J A W |
1 | 1 | 0 | 0 | 1 | 8 1 J A |
1 | 1 | 0 | 1 | 0 | D 8 1 J |
1 | 1 | 0 | 1 | 1 | S D 8 1 |
1 | 1 | 1 | 0 | 0 | I S D 8 |
1 | 1 | 1 | 0 | 1 | L I S D |
1 | 1 | 1 | 1 | 0 | Y L I S |
1 | 1 | 1 | 1 | 1 | C Y L I |
Note: The symbols between brackets means alternate characters.
If this is not confusing enough, you can only use the table above for the first character of each group of four. For the rest we have to do an arrangement. Depending on the character position. The arrangement is the following: Let pos be the horizontal position of the character (starting in 0) in its group of four characters, then we have to choose the character that is exactly pos cells above in the table of the character corresponding to the bit combination we have for that character. (I think the last sentence is a bit confusing) Let's see it in an example:
In the initial password, we have 000 arrows, 000 coins and 000 keys. So let's derive the first block of 4 characters. As the codification of the zero in BCD is 0000, all the bits are zero.
Therefore, we have the final solution: UR3F.
know that these explanations can be very confusing. So, I've included the algorithm to compute the 10 first characters of the MoG passwords:
void digit2BCD(int d,int bits[4])
{
if ((d&1)!=0) bits[0]=1;
else bits[0]=0;
if ((d&2)!=0) bits[1]=1;
else bits[1]=0;
if ((d&4)!=0) bits[2]=1;
else bits[2]=0;
if ((d&8)!=0) bits[3]=1;
else bits[3]=0;
}
void writebits(int bits[4],int desination[],int start)
{
int i;
for(i=0;i<4;i++) destination[start+i]=bits[i];
}
char obtaincharacter(int bits[],int start,int pos)
{
char table[32]="U72G4X5BKN90PQTHVE6OMWAJ---S-F3R";
int index;
index=bits[start]*16+bits[start+1]*8+bits[start+2]*4+bits[start+3]*2+bits[start+4];
index=index - (pos % 4);
if (index<0) index=index+32;
return table[index];
}
void generatePASSWORD(int arrowdigits[3],int coindigits[3],int keydigits[3],char digits[10])
{
int i;
int bits[4];
int dbits[50];
digit2BCD(arrowdigits[0],bits);
writebits(bits,dbits,12);
digit2BCD(arrowdigits[1],bits);
writebits(bits,dbits,0);
digit2BCD(arrowdigits[2],bits);
writebits(bits,dbits,4);
digit2BCD(coindigits[0],bits);
writebits(bits,dbits,28);
digit2BCD(coinddigits[1],bits);
writebits(bits,dbits16);
digit2BCD(coinddigits[2],bits);
writebits(bits,dbits,20);
digit2BCD(keydigits[0],bits);
writebits(bits,dbits,44);
digit2BCD(keydigits[1],bits);
writebits(bits,dbits,36);
digit2BCD(keydigits[2],bits);
writebits(bits,dbits,32);
for(i=0;i<10;i++) {
digits[i]=obtaincharacter(dbits,i*5,i%4);
}
}
Calling this algorithm with:
char digits[10]; generatePASSWORD({1,0,0},{1,0,0},{1,0,0},digits);
will write in the digits array the folloing data: UR3QUR5FUG
That when used in a MoG password as follows results in a game where we have 100 arrows, 100 coins and 100 keys:
R3Q UR5F UG4F 423R UR3F UR3F UR3F UR3F UR3F UR3F URS4 A
To generate the last 2 digits I've used the method explained in the previous post.You can try this passwod and see that it works!!!!
So this is all for today!
Let's go with the objects today. They are stored in the white section:
R3Q UR5F UG4F 423R
UR3F UR3F UR3F UR3F
UR3F UR3F URS4 A
Using the same schema as we used to decode the keys, arrows and coins (Each character storing 5 bits). This has been easier to decode. Since we have 9 characters, we have 9*5 = 45 bits, each one storing if we have an object or not. Here I put a table showing the mapping between bits and objects:
Bit | Object |
---|---|
R |
bit 1 - arrows bit 2 - ceramic arrows bit 3 - Rolling fire bit 4 - Fire bit 5 - Mines |
3 |
bit 1 - magnifing glass bit 2 - - bit 3 - - bit 4 - - bit 5 - - |
F |
bit 1 - Cross bit 2 - Great Key bit 3 - Necklace bit 4 - Crown bit 5 - Helmet |
U |
bit 1 - Oar bit 2 - Shoes bit 3 - Doll bit 4 - Robe bit 5 - Bell |
R |
bit 1 - Halo bit 2 - Candle bit 3 - Armour bit 4 - Carpet bit 5 - Helm |
3 |
bit 1 - Lamp bit 2 - Vase bit 3 - Pendant bit 4 - Earrings bit 5 - Bracelet |
F |
bit 1 - Ring bit 2 - Bible bit 3 - Harp bit 4 - Triangle bit 5 - Trumpet Shell |
U |
bit 1 - Pitcher bit 2 - Sabre bit 3 - Dagger bit 4 - Feather bit 5 - Shield (*) |
R |
bit 1 - Bread and Water bit 2 - Salt bit 3 - Silver Shield (*) bit 4 - Gold Shield (*) bit 5 - - |
(*) If the "Shield" bit is 1, it means that one shield is owned. Then if both "Silver Shield" and "Gold Shield" bits are 0 the bronze shield is owned; but if the "Silver Shield" or "Gold Shield" are activated, indicate the type of shield we have. They cannot be both equal to 1.
Well, easy actualization for today! Tomorrow or may be the other I'll try to decode more zones.
It's the turn of the life-meters to be decoded. Let's asume that a 4 bit number encodes the life of each character. Where 0001 means the initial life, 0010 the life after collecting one world key, 0011 after collecting two, etc... With this supposition, and analyzing various codes, we can see how the life is encoded in the last 5 characters of the first line:
---- ---- ---F 423R
F | 4 | 2 | 3 | R |
---|---|---|---|---|
bit 0 - - bit 1 - - bit 2 - - bit 3 - - bit 4 - alb0 |
bit 0 - alb1 bit 1 - alb2 bit 2 - alb3 bit 3 - - bit 4 - - |
bit 0 - - bit 1 - - bit 2 - - bit 3 - 1 bit 4 - 1 |
bit 0 - - bit 1 - - bit 2 - - bit 3 - - bit 4 - - |
bit 0 - plb0 bit 1 - plb1 bit 2 - plb2 bit 3 - plb3 bit 4 - - |
Where alb0,alb1,alb2,alb3 are the bits storing Aphrodite's life, and plb0,plb1,plb2,plb3 are the bits storing Popolon's life.
Today, just a correction. Christian Javier d'Orazio from Argentina has emailed me about an error in the decoding of the life-meter information. With his help, now I have the right decoding.
Now I know that 5 bits encode the life of each character instead of 4 as I originally thought. I discovered also that the maximum experience is stored in the codes (a bit stupid, since the maximum experience cannot vary during the game!!!) We can see now, how the life is encoded in the last 6 characters of the first line:
---- ---- --4F 423R
4 | F | 4 | 2 | 3 | R |
---|---|---|---|---|---|
bit 0 - aeb0 bit 1 - aeb1 bit 2 - aeb2 bit 3 - aeb3 bit 4 - aeb4 |
bit 0 - - bit 1 - - bit 2 - - bit 3 - alb0 bit 4 - alb1 |
bit 0 - alb2 bit 1 - alb3 bit 2 - alb4 bit 3 - - bit 4 - - |
bit 0 - - bit 1 - peb0 bit 2 - peb1 bit 3 - peb2 bit 4 - peb3 |
bit 0 - peb4 bit 1 - - bit 2 - - bit 3 - - bit 4 - plb0 |
bit 0 - plb1 bit 1 - plb2 bit 2 - plb3 bit 3 - plb4 bit 4 - - |
Where alb0,...,alb4 are the bits storing Aphrodite's life, and plb0,...,plb4 are the bits storing Popolon's life and aeb0,...,aeb4 and peb0,...,peb4 are the bits storing the maximum experience.
I've tried to decode the single character that stores which characters are alive and which is the active character, but I think that more information is stored there.
UR3F UR3F UR4F 423R
UR3F UR3F UR3F UR3F
UR3F UR3F UR S4 8
When you obtain the code with POPOLON, Two values are possible: S and D, and when obtained with APHRODITE, the possible values are P and 9. The following table summarizes it:
Character | Binary value | Meaning |
---|---|---|
S | 11101 | Popolon active |
P | 01110 | Aphrodite active |
D | 11100 | Popolon active, Aphrodite dead |
9 | 01100 | Aphrodite active, Popolon dead |
Looking at the previous table, it is obvious that the first bit encodes the active character (1 = Popolon, 0 = Aphrodite). Then there are two bits that are always 1 (and that I do not know what are they encoding), then the last two bits store whether the characters are dead or alive.
You can try to set to zero the second and third bits, for instance if we put an H (binary 10001), the game behaves exactly equal to with an S!!! I have still to investigate a little more...
I've done the world's information decoding too! The world information is stored as follows. I show three tables, one for the first 8 characters of the second row, another for the last 8 characters, and the last for the first character of the third row:
U | R | 3 | F | U | R | 3 | F |
---|---|---|---|---|---|---|---|
bit 0 - - bit 1 - - bit 2 - - bit 3 - - bit 4 - - |
bit 0 - r1 bit 1 - c1 bit 2 - w1 bit 3 - m1 bit 4 - - |
bit 0 - s01 bit 1 - s11 bit 2 - s21 bit 3 - r2 bit 4 - c2 |
bit 0 - w2 bit 1 - m2 bit 2 - - bit 3 - s20 bit 4 - s21 |
bit 0 - s22 bit 1 - r3 bit 2 - c3 bit 3 - w3 bit 4 - m3 |
bit 0 - - bit 1 - s03 bit 2 - s13 bit 3 - s23 bit 4 - r4 |
bit 0 - c4 bit 1 - w4 bit 2 - m4 bit 3 - - bit 4 - s04 |
bit 0 - s14 bit 1 - s24 bit 2 - r5 bit 3 - c5 bit 4 - w5 |
U | R | 3 | F | U | R | 3 | F |
---|---|---|---|---|---|---|---|
bit 0 - m5 bit 1 - - bit 2 - s05 bit 3 - s15 bit 4 - s25 |
bit 0 - - bit 1 - r6 bit 2 - c6 bit 3 - w6 bit 4 - m6 |
bit 0 - s06 bit 1 - s16 bit 2 - s26 bit 3 - r7 bit 4 - c7 |
bit 0 - w7 bit 1 - m7 bit 2 - - bit 3 - s07 bit 4 - s17 |
bit 0 - s27 bit 1 - r8 bit 2 - c8 bit 3 - w8 bit 4 - m8 |
bit 0 - - bit 1 - s08 bit 2 - s18 bit 3 - s28 bit 4 - r9 |
bit 0 - c9 bit 1 - w9 bit 2 - m9 bit 3 - - bit 4 - s09 |
bit 0 - s19 bit 1 - s29 bit 2 - r10 bit 3 - c10 bit 4 - w10 |
U |
---|
bit 0 - m10 bit 1 - s010 bit 2 - s110 bit 3 - s210 bit 4 - - |
And that's all! We have decoded the MoG passwords!! Just one thing, the table posted day 5-3-2002 contains alternate characters for some values. I will tell you now when we have to use one or another.
We have 36 possible characters (10 digits, and 26 letters), sorted in the following way:
F3RU72G4X5BKN90PQTHVE6OMWAJ18DSILYCZ
The first character of each block of four uses:
U72G4X5BKN90PQTHVE6OMWAJ18DSILYC
The second character uses:
RU72G4X5BKN90PQTHVE6OMWAJ18DSILY
The third:
3RU72G4X5BKN90PQTHVE6OMWAJ18DSIL
And the fourth:
F3RU72G4X5BKN90PQTHVE6OMWAJ18DSI
Notice that the Z is never used (but I put it there just because is the only letter that doesn't appear). To obtain the binary value of any combination, suppose we have the block:
423R
So we have the information: (4,3,0,2) and transforming it to binary: 00100,00011, 000000, 00010.
I think that's all!! I'm going now to start including the password system into the remake!!
See you ;)
Well, 3 months after the last update I've finally completed the password system. The two unknown bits in the character encoding whether Aphrodite and Popolon are dead or alive at last have revealed its use:
UR3F UR3F UR4F 423R
UR3F UR3F UR3F UR3F
UR3F UR3F UR S4 8
The character function is the following:
Character | Binary value | Meaning |
---|---|---|
S | 1xy01 | Popolon active |
P | 0xy10 | Aphrodite active |
D | 1xy00 | Popolon active, Aphrodite dead |
9 | 0xy00 | Aphrodite active, Popolon dead |
Where x and y mean:
Well, that's all!
LARS the 18TH has noticed several bug in this page, all the corrections are made, and marked in RED. Thanks LARS!!