nancygold's Journal
 
[Most Recent Entries] [Calendar View] [Friends View]

Saturday, June 22nd, 2024

    Time Event
    12:37a
    Have you ever seen this PRNG?
    I've decided to look into the game's code out of curiosity.
    Among the usual stuff, like EMS init, it seeds a random number generator.
    Not a usual one, but with a 48-bit state.
    Googled but could not find its origin.
    Additionally, the game seeds that PRNG from the 40:6C at BDA.
    Not something you usually see, since the Borland's C library provides a time access functions.

    The game appears to be also using a custom EMS library, since it doesn't appear to match any of the free or shareware ones.
    // ChatGPT claims it resembles the:
    // 8-bit Maxim Integrated (formerly Dallas Semiconductor) one-wire CRC algorithm
    
    
    //48-bit shift register
    static uint8_t s[6]; //state
    
    uint8_t rand8() { //1000:0730
      int i,c;
      uint8_t *src, *dst;
      //sum 1st, 4th and 5th bytes into the 0th byte
      c = s[1] + s[4] + 1;
      if (c&0x100) c = (c&0xFF) + 1;
      s[0] = (c + s[5])&0xFF;
    
      //shieft right by 8 bites
      src = s + 4;
      dst = s + 5;
      for (i = 5; i != 0; i = --i) *dst-- = *src--;
    
      return s[0];
    }
    
    void srand8(uint32_t seed) { //1000:0730
      int i;
      uint8_t *pseed;
    
      seed ^= 0x55555555;
      pseed = (uint8_t*)&seed;
      s[0] = 0;
      s[1] = pseed[0];
      s[2] = pseed[1];
      s[3] = pseed[2];
      s[4] = pseed[3];
      s[5] = 0;
      for (i = 0; i < 200; i++) rand8();
      return;
    }



    It is similar to the below code:
    uint8_t rand48() {
        // Get the current state
        uint64_t s = get_state();
    
        // Apply bitwise transformations to update the state using only addition and shifting
        s = ((s << 13) | (s >> (48 - 13))) + 0xB;
        s &= ((1ULL << 48) - 1);
    
        // Store the updated state
        set_state(s);
    
        // Return the top 8 bits of the state
        return (s >> 40) & 0xFF;
    }
    




    Current Mood: amused
    11:17a
    Apparently 48-bit PRNGs were popular at one point
    One even came with SVr1 Unix in 1983, called rand48 (drand48.s), which was state of art at the time:
    https://sci-hub.ru/10.1002/j.1538-7305.1982.tb03099.x (thanks Putin and FSB for funding sci-hub)

    Yet the Unix one produced entire 32-bit number, while the PRNG I encountered uses all 48 bits to generate a single byte.

    Current Mood: amused

    << Previous Day 2024/06/22
    [Calendar]
    Next Day >>

About LJ.Rossia.org