Quante combinazioni di md5sum possono essere calcolate da una chiamata a random () in PostgreSQL?

2

Spazio problema

Sono molto al di fuori del mio voto, sto cercando di capire

  • Quanta casualità fornisce effettivamente una chiamata a random () in PostgreSQL?

    SELECT random();
    
  • Indipendentemente dal fatto che tu possa ragionevolmente indovinare quella gran casualità?

Che cosa so

  1. So che non è così casuale come la gente vuole che sia, è solo inefficiente. Dopo aver concluso molto tempo fa che md5() è una perdita di tempo, posso solo confrontare le dimensioni.

    --produces "8" (in bytes)
    SELECT pg_column_size(random());
    
    --produces "36" (in bytes)
    SELECT pg_column_size(md5(random()::text));
    

    Questo è un sacco di spazio sprecato. So che possiamo memorizzare md5 () in UUID che impiegherà 16 byte. Ma sono ancora 8 byte di spazio di scarto dal nostro originale 8 byte random ().

  2. So che PostgreSQL al momento genera numeri casuali come questo ,

    result = (double) random() / ((double) MAX_RANDOM_VALUE + 1);
    
    PG_RETURN_FLOAT8(result);
    

    E so che PG_RETURN_FLOAT8(result) è una macro che chiama Float8GetDatum(result) .

  3. I documenti su random() dicono questo,

    The characteristics of the values returned by random() depend on the system implementation. It is not suitable for cryptographic applications; see pgcrypto module for an alternative.

  4. Credo che 8 byte float, sia un float standard IEEE 754 sotto il cofano, anche dai documenti.

    The data types real and double precision are inexact, variable-precision numeric types. In practice, these types are usually implementations of IEEE Standard 754 for Binary Floating-Point Arithmetic (single and double precision, respectively), to the extent that the underlying processor, operating system, and compiler support it.

  5. So che la precisione completa di IEEE 754 supporta i seguenti stati che il nostro random() non supporta.

    1. Numeri negativi
    2. Non-a-number
    3. Infinity
    4. Infinito negativo
  6. So che IEEE riserva 11 bit per l'esponente , e siamo sicuri di averlo in una posizione che produce numeri nell'intervallo di (0,1) . Dai documenti ,

    random value in the range 0.0 <= x < 1.0.

  7. Non sono sicuro di quanto accurato (preferirei che ciò sia verificato con le informazioni di cui sopra), ma per un Doppio documento di 8 byte dice

    variable-precision, inexact 15 decimal digits precision

Con tutto questo c'è qualcuno abbastanza fluente in 754, e C per dirmi davvero quanto sia casuale una chiamata a random() .

Perché sto chiedendo

Ho suggerito di generare le chiavi di sessione che non utilizzano md5(random()::text) memorizzate nel testo, ma invece di usare pgcrypto 's gen_random_uuid() ora mi chiedo quanto conta.

    
posta Evan Carroll 12.01.2017 - 10:25
fonte

1 risposta

3

random () può avere al massimo 64 bit di significatività, poiché è un float a doppia precisione. Ciò presuppone la generazione di numeri casuali perfetti e tutto il resto.

Produciamo solo un significato casuale, il segno e l'esponente sono fissi. La parte frazionaria del significato è di 52 bit.

Quindi ... circa 2 ^ 52 possibili valori.

Sembra che tu stia pensando alla tabella arcobaleno come una mappatura dell'md5 della rappresentazione testuale di una precisione doppia che torna al float originale. Supponendo che tu stia utilizzando extra_float_digits = 3 , ciò richiederebbe circa 128 * 2^52 byte, quindi un paio di exabyte, in cambio della riduzione dello spazio di ricerca da 2 ^ 128 a 2 ^ 52. Non così eccitante, davvero.

Vorrei ancora una buona ragione per non utilizzare solo uuid-ossp di uuid_generate_v4() . Quanto possono essere grandi le tue tabelle di sessione? Sai che PostgreSQL ha enorme overhead per riga giusto ?

Separatamente, non devi usare uuid per memorizzare un md5 , o formattarlo come testo. Puoi anche utilizzare bytea . Sarà racchiuso in un Datum a breve varlena che ha una lunghezza di 1 byte, quindi occuperà 17 byte. (Vedi: VARSIZE_ANY in src/include/postgres.h e src/backend/utils/adt/varlena.c ).

    
risposta data 12.01.2017 - 10:39
fonte

Leggi altre domande sui tag