Why does my Go implementation of xorshift128+ not produce the same results as JavaScript?

  Kiến thức lập trình

I am trying to implement a PNRG (xorshift128+) that will match when generated on the client (Go) and the server (Node).

Here is the JS code:

function xor128(aT, Gj) {
     var SM = aT;
     var tn = Gj;
     return function() {
         var Fv = SM;
         Fv ^= Fv << 23;
         Fv ^= Fv >> 17;
         var RW = tn;
         Fv ^= RW;
         SM = RW;
         Fv ^= RW >> 26;
         tn = Fv;
         return (SM + tn) % 4294967296;
     };
 }

buildKeyArray(section, max, seed) {
    const randomNumberGenerator = xor128(section, seed);
    const outputArray = [];

    for (let index = 0; index < max; index++) {
        const a = randomNumberGenerator()
        outputArray.push(a & 255);
    }

    return outputArray;
}

And here is my attempted implementation of the client (Go) code:

type Xor128Generator struct {
    SM uint32
    tn uint32
}

func NewXor128Generator(aT, Gj uint32) *Xor128Generator {
    return &Xor128Generator{SM: aT, tn: Gj}
}

func (x *Xor128Generator) Generate() uint32 {
    Fv := x.SM
    Fv ^= Fv << 23
    Fv &= 0xFFFFFFFF // 32-bit wrap around
    Fv ^= Fv >> 17
    Fv &= 0xFFFFFFFF // 32-bit wrap around
    RW := x.tn
    Fv ^= RW
    Fv &= 0xFFFFFFFF // 32-bit wrap around
    x.SM = RW
    Fv ^= RW >> 26
    Fv &= 0xFFFFFFFF // 32-bit wrap around
    x.tn = Fv

    result := uint32(x.SM) + uint32(x.tn)
    return uint32(result)
}

func (x *XorEncoder) buildKeyArray() []byte {
    gen := NewXor128Generator(x.XorSection, x.Xor128Seed)
    outputArray := make([]byte, x.Xor128Max)

    for index := 0; index < x.Xor128Max; index++ {
        var a = gen.Generate()
        outputArray[index] = byte(a & 255)
    }

    return outputArray
}

The issue is that my Go implementation is generating different numbers from the xor128 code. I understand this is because of Node making use of 32-bit integers, and Go using 64-bit integers. However how can I fix the Go code so that it will be consistent with the JS code and generate the same numbers on both platforms.

To be clear, the JS code is generating the correct values, and the Go code needs to match.

LEAVE A COMMENT