I've solved this.
I was stupidly using a single byte to hold each integer in the hash table. This was due to seeing things like hash_tab[idx]
in C, which my PHP brain translated to $hash_tab{$idx}
which of course is wrong. It would be substr($hash_tab,$idx,$idx+4)
I was also failing to see that the hash table "size" was the number of strings and not the byte length.
My sample code works now. My generated table matches that pulled from the MO file.