RESSU 1.8

Ressun edellisessä versiossa(1.7) oli ongelma että myös perusriveistä laskettiin teoreettisia satunnaisbittejä. Tässä pyritään laskemaan mukaan ainoastaan poikkeukset säännöstä. Jos esimerkiksi perusketjut ovat kuuden merkin pituisia, tämän pitäisi laskea vain kuudesta poikkeavat ketjut, eli seiskat ja viitoset kuten edellisen postin esimerkissä. Tällä tavoin teoreettisten satunnaisbittien lukumäärä on lähempänä oikeata.

Tässä varsinainen uusi koodi kokonaisuudessaan, muutetut rivit kuvataan postin lopussa: Kuvaus koodista löytyy edellisestä postista http://moijari.com/?p=798.

void ressu_genbytes(int size, unsigned
    char *buffer) /* (c) JariK 2013-2020 v1.8 */
{
  int c, d, e, f, g,
    byte, prevbyte,
    clockbytes = 0, rndbits = 0,
    chainbytes = 0, oldindex = 0, oldcount;
  unsigned char olddata[10];

  memset(olddata, 0, sizeof(olddata));
  prevbyte=clockbyte();
  f=0;

  for(c=0; c<8 || c%8!=0 ||
      clockbytes<2000 ||
      rndbits < 8*size; c++) {
    for(d=0; d<size; d++) {
      e = buffer[d];
      e = ((e&0x80)>>7) | ((e&0x7f)<<1);
      byte = clockbyte();
      buffer[d] = e^byte;
      if(prevbyte != byte) {
        prevbyte = byte;
        olddata[oldindex] = chainbytes;
        oldindex = (oldindex + 1)
            % sizeof(olddata);
        oldcount = 0;
        for(g=0; g < sizeof(olddata); g++) {
          if(olddata[g] == chainbytes)
            oldcount++;
        }
        if(oldcount < 4)
          rndbits++;

        clockbytes += chainbytes;
        chainbytes = 0;
      } // if(prevbyte
      chainbytes++;
    } // for(d=0
    for(d=0; d<size; d++) {
      f = (f+buffer[d])%size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    } // for(d=0
  } // for(c=0
}

Lisätyt muuttujat: chainbytes sisältää tämän ketjun pituuden, oldindex kertoo, mihin “positioon” olddata taulussa seuraava ketjun pituus laitetaan, oldcount kenttään lasketaan tämänpituisten ketjujen lukumäärä ja olddata taulukkoon kirjoitetaan viimeisten kymmenen ketjun pituudet.

  int chainbytes = 0, oldindex = 0, oldcount;
  unsigned char olddata[10];

Tyhjennetään olddata taulukko:

  memset(olddata, 0, sizeof(olddata));

Olddata taulussa pidetään yllä kymmentä viimeistä ketjun pituutta, ja tässä uusi ketjun pituus lisätään tauluun: Oldindex kentän arvoa kasvatetaan aina uuden pituuden lisäyksen jälkeen yhdellä. Jos oldindex menee ympäri, aloitetaan taas nollasta.

  olddata[oldindex] = chainbytes;
  oldindex = (oldindex + 1) % sizeof(olddata);

Lasketaan kuinka monta edellisen pituista lohkoa taulussa on:

  oldcount = 0;
  for(g=0; g<sizeof(olddata); g++) {
    if(olddata[g] == chainbytes)
      oldcount++;
  }

Lisätään bitti satunnaisuuteen vain jos esiintymiä on vähemmän kuin 4:

  if(oldcount < 4)
    rndbits++;

Lisätään tämän ketjun pituus kokonaispituuteen ja nollataan tämän ketjun pituus:

  clockbytes += chainbytes;
  chainbytes = 0;

Lasketaan tämän ketjun pituutta.

  chainbytes++;

Apuohjelmat ja tarkemman kuvauksen saat tietysti edellisestä postista.

Leave a Reply