[text] seedrandom.php

Viewer

copydownloadembedprintName: seedrandom.php
  1. * @param {number=} overflow 
  2.  * @param {number=} startdenom
  3.  */
  4.  
  5. //função anônima
  6. (function (pool, math, width, chunks, significance, overflow, startdenom) {
  7.  
  8.   //
  9.   // seedrandom()
  10.   // Esta é a função seedrandom descrita acima.
  11.   //
  12.   math['seedrandom'] = function seedrandom(seed, use_entropy) {
  13.     var key = [];
  14.     var arc4;
  15.   
  16.     // Achatamos a string de semente ou construímos uma a partir da entropia local, se necessário.
  17.     seed = mixkey(flatten(
  18.       use_entropy ? [seed, pool] :
  19.       arguments.length ? seed :
  20.       [new Date().getTime(), pool, window], 3), key);
  21.   
  22.     // Usamos a semente para inicializar um gerador ARC4.
  23.     arc4 = new ARC4(key);
  24.   
  25.     // Misturamos a aleatoriedade na entropia acumulada.
  26.     mixkey(arc4.S, pool);
  27.   
  28.     // Substituímos Math.random
  29.   
  30.     // Esta função retorna um número aleatório em [0, 1) que contém
  31.     // aleatoriedade em cada bit da mantissa do valor IEEE 754.
  32.   
  33.     math['random'] = function random() {  // Closure para retornar um número aleatório:
  34.       var n = arc4.g(chunks);             // Começamos com um numerador n < 2 ^ 48
  35.       var d = startdenom;                 //   e denominador d = 2 ^ 48.
  36.       var x = 0;                          //   e sem 'último byte extra'.
  37.       while (n < significance) {          // Preenchemos todos os dígitos significativos por
  38.         n = (n + x) * width;              //   deslocamento do numerador e
  39.         d *= width;                       //   denominador e gerando um
  40.         x = arc4.g(1);                    //   novo byte menos significativo.
  41.       }
  42.       while (n >= overflow) {             // Para evitar arredondamento para cima, antes de adicionar
  43.         n /= 2;                           //   último byte, deslocamos tudo
  44.         d /= 2;                           //   para a direita usando matemática de inteiros até
  45.         x >>>= 1;                         //   termos exatamente os bits desejados.
  46.       }
  47.       return (n + x) / d;                 // Formamos o número dentro de [0, 1).
  48.     };
  49.   
  50.     // Retornamos a semente que foi usada
  51.     return seed;
  52.   };
  53.   
  54.   //
  55.   // ARC4
  56.   //
  57.   // Uma implementação ARC4. O construtor recebe uma chave na forma de
  58.   // uma matriz de no máximo (largura) inteiros que devem ser 0 <= x < (largura).
  59.   //
  60.   // O método g(contagem) retorna um número pseudorrandômico que concatena
  61.   // as próximas (contagem) saídas de ARC4. Seu valor de retorno é um número x
  62.   // que está no intervalo 0 <= x < (largura ^ contagem).
  63.   //
  64.   /** @constructor */
  65.   function ARC4(key) {
  66.     var t, u, me = this, keylen = key.length;
  67.     var i = 0, j = me.i = me.j = me.m = 0;
  68.     me.S = [];
  69.     me.c = [];
  70.   
  71.     // A chave vazia [] é tratada como [0].
  72.     if (!keylen) { key = [keylen++]; }
  73.   
  74.     // Configuramos S usando o algoritmo padrão de programação de chaves.
  75.     while (i < width) { me.S[i] = i++; }
  76.     for (i = 0; i < width; i++) {
  77.       t = me.S[i];
  78.       j = lowbits(j + t + key[i % keylen]);
  79.       u = me.S[j];
  80.       me.S[i] = u;
  81.       me.S[j] = t;
  82.     }
  83.   
  84.     // O método "g" retorna as próximas (contagem) saídas como um número.
  85.     me.g = function getnext(count) {
  86.       var s = me.S;
  87.       var i = lowbits(me.i + 1); var t = s[i];
  88.       var j = lowbits(me.j + t); var u = s[j];
  89.       s[i] = u;
  90.       s[j] = t;
  91.       var r = s[lowbits(t + u)];
  92.       while (--count) {
  93.         i = lowbits(i + 1); t = s[i];
  94.         j = lowbits(j + t); u = s[j];
  95.         s[i] = u;
  96.         s[j] = t;
  97.         r = r * width + s[lowbits(t + u)];
  98.       }
  99.       me.i = i;
  100.       me.j = j;
  101.       return r;
  102.     };
  103.     // Para imprevisibilidade robusta, descartamos um lote inicial de valores.
  104.     // Veja http://www.rsa.com/rsalabs/node.asp?id=2009
  105.     me.g(width);
  106.   }
  107.   
  108.   //
  109.   // flatten()
  110.   // Converte uma árvore de objetos em matrizes aninhadas de strings.
  111.   //
  112.   /** @param {Object=} result 
  113.     * @param {string=} prop */
  114.   function flatten(obj, depth, result, prop) {
  115.     result = [];
  116.     if (depth && typeof(obj) == 'object') {
  117.       for (prop in obj) {
  118.         if (prop.indexOf('S') < 5) {    // Evitamos o bug do FF3 (local/sessionStorage)
  119.           try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
  120.         }
  121.       }
  122.     }
  123.     return result.length ? result : '' + obj;
  124.   }
  125.   
  126.   //
  127.   // mixkey()
  128.   // Mistura uma semente de string em uma chave que é uma matriz de inteiros, e
  129.   // retorna uma semente de string encurtada que é equivalente à chave resultante.
  130.   //
  131.   /** @param {number=} smear 
  132.     * @param {number=} j */
  133.   function mixkey(seed, key, smear, j) {
  134.     seed += '';                         // Garantimos que a semente seja uma string
  135.     smear = 0;
  136.     for (j = 0; j < seed.length; j++) {
  137.       key[lowbits(j)] =
  138.         lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j));
  139.     }
  140.     seed = '';
  141.     for (j in key) { seed += String.fromCharCode(key[j]); }
  142.     console.log(seed);
  143.     return seed;
  144.   }
  145.   
  146.   //
  147.   // lowbits()
  148.   // Um rápido "n mod largura" para largura uma potência de 2.
  149.   //
  150.   function lowbits(n) { return n & (width - 1); }
  151.   
  152.   //
  153.   // As seguintes constantes estão relacionadas aos limites IEEE 754.
  154.   //
  155.   startdenom = math.pow(width, chunks);
  156.   significance = math.pow(2, significance);
  157.   overflow = significance * 2;
  158.   
  159.   //
  160.   // Quando seedrandom.js é carregado, misturamos imediatamente alguns bits
  161.   // do RNG incorporado no pool de entropia. Porque não queremos interferir
  162.   // com o estado determinístico do PRNG mais tarde,
  163.   // seedrandom não chamará math.random por conta própria novamente após
  164.   // a inicialização.
  165.   //
  166.   mixkey(math.random(), pool);
  167.  
  168.   // Fim do escopo anônimo e passagem de valores iniciais.
  169.   })(
  170.   [], // pool: o pool de entropia começa vazio
  171.   Math, // math: pacote contendo random, pow e seedrandom
  172.   256, // width: cada saída RC4 é 0 <= x < 256
  173.   6, // chunks: pelo menos seis saídas RC4 para cada número duplo
  174.   52 // significance: há 52 dígitos significativos em um número duplo
  175.   );

Editor

You can edit this paste and save as new:


File Description
  • seedrandom.php
  • Paste Code
  • 30 Apr-2024
  • 6.03 Kb
You can Share it: