Ok, this is gonna be difficult for me because Java doesn't support unsigned numbers, so I hope this helps
First this piece of your code is the rand() function that will give you the next seed, however seems you are using the same seed for all bytes
Instead use a method and a static variable
static long seed;
public static long rand(){
seed = (0x41C64E6D * seed + 0x6073) & 0xFFFFFFFF; //This is to make sure it is an unsigned integer
return seed>>>16;
}
Before you assign decrypt the bytes, you must now which order are the blocks shuffled, and the XOR is applied on an Unsigned Short, not a byte
First determine the block order using the pid
int a = Math.round(((pid & 0x3E000) >> 0xD) % 24);
String order = "";
switch (a){ //Determine block order
case 0:
order = "ABCD";
break;
case 1:
order = "ABDC";
break;
case 2:
order = "ACBD";
break;
case 3:
order = "ACDB";
break;
case 4:
order = "ADBC";
break;
case 5:
order = "ADCB";
break;
case 6:
order = "BACD";
break;
case 7:
order = "BADC";
break;
case 8:
order = "BCAD";
break;
case 9:
order = "BCDA";
break;
case 10:
order = "BDAC";
break;
case 11:
order = "BDCA";
break;
case 12:
order = "CABD";
break;
case 13:
order = "CADB";
break;
case 14:
order = "CBAD";
break;
case 15:
order = "CBDA";
break;
case 16:
order = "CDAB";
break;
case 17:
order = "CDBA";
break;
case 18:
order = "DABC";
break;
case 19:
order = "DACB";
break;
case 20:
order = "DBAC";
break;
case 21:
order = "DBCA";
break;
case 22:
order = "DCAB";
break;
case 23:
order = "DCBA";
break;
}
Then initialize the seed with the checksum, pkm+(pkm[b+1]<<8) will give you the short for the XOR
int checksum = 0x27dd; //Beginning seed is the checksum
seed = checksum;
byte[] x = new byte[136];
int b = 8;
long temp=0;
for (b=8;b<136;){
switch (order.substring(0, 1)){ //Depending on the order unshuffle bytes
case "A":
for (int j=8; j<0x28; j+=2){
temp = (long) (((pkm[b]+(pkm[b+1]<<8)))^(rand()));
x[j+1] = (byte) ((byte)((temp & 0xFF00)>>>8));
x[j] = (byte) ((byte) temp & 0xFF);
b+=2;
}
order = order.replace("A","");
break;
case "B":
for (int j=0x28; j<0x48; j+=2){
temp = (long) (((pkm[b]+(pkm[b+1]<<8)))^(rand()));
x[j+1] = (byte) ((byte)((temp & 0xFF00)>>>8));
x[j] = (byte) ((byte) temp & 0xFF);
b+=2;
}
order = order.replace("B","");
break;
case "C":
for (int j=0x48; j<0x68; j+=2){
temp = (long) (((pkm[b]+(pkm[b+1]<<8)))^(rand()));
x[j+1] = (byte) ((byte)((temp & 0xFF00)>>>8));
x[j] = (byte) ((byte) temp & 0xFF);
b+=2;
}
order = order.replace("C","");
break;
case "D":
for (int j=0x68; j<0x88; j+=2){
temp = (long) (((pkm[b]+(pkm[b+1]<<8)))^(rand()));
x[j+1] = (byte) ((byte)((temp & 0xFF00)>>>8));
x[j] = (byte) ((byte) temp & 0xFF);
b+=2;
}
order = order.replace("D","");
break;
}
}
Then just write x[] from 0 to 136, the bytes will be in the correct order