Zamiel

get_seed.c

Aug 11th, 2017
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.50 KB | None | 0 0
  1. /*
  2.     Compile with:
  3.     g++ -std=c++11 get_seed.c -o get_seed
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <random>
  10. #include <string>
  11.  
  12. const char *g_charSet = "ABCDEFGHJKLMNPQRSTWXYZ01234V6789";
  13. unsigned char g_charLookup[256];
  14.  
  15. void initCharLookup() {
  16.     memset(g_charLookup, 0xFF, sizeof(g_charLookup));
  17.  
  18.     int i = 0;
  19.     for (const char *p = g_charSet; *p; ++p, ++i) {
  20.         g_charLookup[*p] = i;
  21.     }
  22. }
  23.  
  24. unsigned int string2seed(const std::string &str) {
  25.     int n = str.size();
  26.  
  27.     // Must be 9 character long
  28.     if (n != 9) {
  29.         return 0;
  30.     }
  31.  
  32.     // 5th character must be a whitespace
  33.     if (str[4] != ' ') {
  34.         return 0;
  35.     }
  36.  
  37.     // Convert into a 64-bit seed
  38.     unsigned char bytes[8];
  39.     for(int i = 0; i < 9; ++i) {
  40.         if (i == 4) {
  41.             continue;
  42.         }
  43.  
  44.         int j;
  45.         if (i > 4) {
  46.             j = i - 1;
  47.         } else {
  48.             j = i;
  49.         }
  50.         unsigned char b = g_charLookup[(unsigned char)str[i]];
  51.  
  52.         // Invalid character
  53.         if (b == 0xFF) {
  54.             return 0;
  55.         }
  56.  
  57.         bytes[j] = b;
  58.     }
  59.  
  60.     // Reduce to 32 bits
  61.     unsigned int r0 = bytes[0];
  62.     r0 = (r0 << 5) | bytes[1];
  63.     r0 = (r0 << 5) | bytes[2];
  64.     r0 = (r0 << 5) | bytes[3];
  65.     r0 = (r0 << 5) | bytes[4];
  66.     r0 = (r0 << 5) | bytes[5];
  67.     r0 = (r0 << 2) | (bytes[6] >> 3);
  68.     r0 ^= 0xFEF7FFD;
  69.  
  70.     unsigned int r = r0;
  71.     unsigned int d = 0;
  72.  
  73.     while (r != 0) {
  74.         d = (r + d) & 0xFF;
  75.         d = ((d >> 7) + (d << 1)) & 0xFF;
  76.         r >>= 5;
  77.     }
  78.  
  79.     if (d == (bytes[7] | ((bytes[6] << 5) & 0xFF))) {
  80.         return r0;
  81.     } else {
  82.         return 0;
  83.     }
  84. }
  85.  
  86. std::string seed2string(unsigned int seed) {
  87.     // Expand to 64 bits
  88.     unsigned int r = seed;
  89.     unsigned int d = 0;
  90.     while(r != 0) {
  91.         d = (r + d) & 0xFF;
  92.         d = ((d >> 7) + (d << 1)) & 0xFF;
  93.         r >>= 5;
  94.     }
  95.  
  96.     unsigned char bytes[8];
  97.     seed ^= 0xFEF7FFD;
  98.     bytes[0] = (seed >> 27) & 0x1F;
  99.     bytes[1] = (seed >> 22) & 0x1F;
  100.     bytes[2] = (seed >> 17) & 0x1F;
  101.     bytes[3] = (seed >> 12) & 0x1F;
  102.     bytes[4] = (seed >> 7 ) & 0x1F;
  103.     bytes[5] = (seed >> 2 ) & 0x1F;
  104.     bytes[6] = ((d | (seed << 8)) >> 5) & 0x1F;
  105.     bytes[7] = d & 0x1F;
  106.  
  107.     // Convert into valid seed characters
  108.     std::string out = "0000 0000";
  109.  
  110.     for (int i = 0; i < 9; ++i) {
  111.         if (i == 4) {
  112.             continue;
  113.         }
  114.  
  115.         int j;
  116.         if (i > 4) {
  117.             j = i - 1;
  118.         } else {
  119.             j = i;
  120.         }
  121.         out[i] = g_charSet[bytes[j]];
  122.     }
  123.  
  124.     return out;
  125. }
  126.  
  127. int main(int argc, char *argv[]) {
  128.     initCharLookup();
  129.  
  130.     std::default_random_engine gen(time(NULL));
  131.     std::uniform_int_distribution<unsigned int> dist;
  132.  
  133.     unsigned int seed = dist(gen);
  134.     printf("%s\n", seed2string(seed).c_str());
  135.  
  136.     return 0;
  137. }
Advertisement
Add Comment
Please, Sign In to add comment