TerusTheBird

CrazyBus RNG (C translation)

Dec 3rd, 2021
540
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <inttypes.h>
  3.  
  4. inline uint64_t swap64( uint64_t n, _Bool high ) {
  5.     if( high ) {
  6.         return  ( ( n >> 16 ) & 0x0000FFFF00000000 ) |
  7.                 ( ( n << 16 ) & 0xFFFF000000000000 ) |
  8.                 ( n & 0x00000000FFFFFFFF );
  9.     } else {
  10.         return  ( ( n >> 16 ) & 0x000000000000FFFF ) |
  11.                 ( ( n << 16 ) & 0x00000000FFFF0000 ) |
  12.                 ( n & 0xFFFFFFFF00000000 );
  13.     }
  14. }
  15.  
  16. // RNG state
  17. uint64_t rnd;
  18.  
  19. uint32_t long_rnd( void ) {
  20.     register uint64_t a,     b;
  21.     //                D0+D1, D2+D3
  22.     a = ( rnd & 0xFFFFFFFFFFFFFF0E ) | 0x20;
  23.     b = a;
  24.     b *= 2;
  25.     a += b;
  26.    
  27.     b = swap64( b, 1 );
  28.     b = swap64( b, 0 );
  29.    
  30.     b = ( b & 0xFFFF0000FFFF0000 ) | ( ( b & 0xFFFF ) << 32 );
  31.     a += b;
  32.     rnd = a;
  33.     return (uint32_t)( a >> 32 );
  34. }
  35.  
  36. uint32_t random_seed( uint64_t seed ) {
  37.     seed += ( seed << 32 );
  38.     rnd = seed;
  39.     return long_rnd();
  40. }
  41.  
  42. uint32_t random_seed_crazybus( uint32_t seed ) {
  43.     uint32_t garbage; // uninitialized
  44.     garbage += seed;
  45.     rnd = garbage; rnd <<= 32; rnd |= seed;
  46.     return long_rnd();
  47. }
  48.  
  49. uint16_t gen_random( uint16_t range ) {
  50.     if( range > 0 )
  51.         range = ( long_rnd() >> 16 ) % range;
  52.     return range;
  53. }
  54.  
  55. // testing
  56. int main( void ) {
  57.     int i;
  58.    
  59.     printf( "%016"PRIX64"\n", rnd );
  60.     random_seed( 1 );
  61.     printf( "%016"PRIX64"\n", rnd );
  62.    
  63.     for( i = 0; i < 16; ++i )
  64.         printf( "%u\n", gen_random( 65535 ) );
  65.    
  66.     return 0;
  67. }
RAW Paste Data