{"id":529,"date":"2018-02-23T02:32:08","date_gmt":"2018-02-23T00:32:08","guid":{"rendered":"https:\/\/moijari.com\/?p=529"},"modified":"2019-11-22T01:52:28","modified_gmt":"2019-11-21T23:52:28","slug":"ressu-versio-1","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=529","title":{"rendered":"Ressu versio 1"},"content":{"rendered":"<p>T\u00e4ss\u00e4 oikeastaan ensimm\u00e4inen &#8220;virallinen&#8221; julkaisu Ressu-satunnaislukugenetaattorin versiosta 1.0.<\/p>\n<p>Edit: muokattu julkaisun j\u00e4lkeisten viikkojen aikana.<\/p>\n<p>Satunnaislukugeneraattorihan koostuu kahdesta funktiosta, clockbyte(), joka palauttaa kellojonon seuraavan merkin, ja ressu_genbytes(), joka on varsinainen generaattori.<\/p>\n<p>Ensimm\u00e4inen kierros genbytes() rutiinista vaihtaa jokaisen merkin bittien j\u00e4rjestyst\u00e4 ja summaa merkkiin seuraavan kellojonon merkin. Ajatuksena on ett\u00e4 jokainen tuloksena tulevan puskurin bitti koskee kaikkia kellojonon merkin bittej\u00e4.<\/p>\n<p>Toinen kierros sekoittaa tulokseksi saadun kellojonon kuin korttipakan k\u00e4yden koko jonon l\u00e4pi, ja vaihtaen kunkin merkin satunnaisen merkin kanssa. Satunnainen merkki valitaan kellojonon merkkien perusteella.<\/p>\n<p>N\u00e4it\u00e4 kahta kierrosta suoritetaan b kertaa, jossa b on kierrosten lukum\u00e4\u00e4r\u00e4 ja m\u00e4\u00e4ritell\u00e4\u00e4n genbytes() kutsussa.<\/p>\n<p>Eli siis kellon tarkin bitti koskettaa merkin tarkinta bitti\u00e4, sen j\u00e4lkeen merkki\u00e4 siirret\u00e4\u00e4n satunnaisesti toiseen kohtaan puskurissa, t\u00e4m\u00e4n j\u00e4lkeen toinen tarkin bitti kellojonosta koskettaa merkin seuraavaa tarkinta bitti\u00e4 ja merkki siirret\u00e4\u00e4n taas. Eli merkin bitit tulevat t\u00e4ysin satunnaisista kellon kohdista ja kaikkien kellon bittien vaikutuskohdat levi\u00e4v\u00e4t tasaisesti puskurissa. Jos kierroksia on kahdeksan, t\u00e4m\u00e4 tehd\u00e4\u00e4n kahdeksan kertaa, ja puskurin kaikki bitit koskettavat kahdeksan kertaa satunnaista kellosignaalin tarkinta bitti\u00e4 ja vaihtavat kosketusten v\u00e4lill\u00e4 paikkojaan.<\/p>\n<p>OWN_CLOCK #define muuttujalla voidaan m\u00e4\u00e4ritell\u00e4 oma clock rutiini. Sit\u00e4 voisi teoriassa k\u00e4ytt\u00e4\u00e4 n\u00e4pp\u00e4imist\u00f6lle tai valokuville.<\/p>\n<p>Viel\u00e4 kerran: eth\u00e4n k\u00e4yt\u00e4 t\u00e4t\u00e4 generaattoria ainoana generaattorina kriittisiin tarkoituksiin, vaan summaat aina useampia generaattoreita..<\/p>\n<pre>\/*\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0* Ressu\u2212satunnaislukugeneraattori versio 1.0 (ressugen.c)\r\n *\r\n * (c)2013\u22122018 Jari Kuivaniemi, Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;sys\/time.h&gt;\r\n\r\nunsigned char *ressu_name = \"Ressu 1.0\";\r\n\r\n#ifndef OWN_CLOCK\r\n\r\nunsigned char clockbyte() \/* JariK 2013 *\/\r\n{\r\n\u00a0 struct timeval tv;\r\n\r\n\u00a0 gettimeofday(&amp;tv,NULL);\r\n\r\n\u00a0 return(tv.tv_usec &amp; 0xff);\r\n}\r\n\r\n#endif\r\n\r\nvoid ressu_genbytes(int size, unsigned char *buffer, int b) \/* JariK 2013 *\/\r\n{\r\n\u00a0 int c,d,e,f;\r\n\r\n\u00a0 f=0;\r\n\u00a0 for(c=0;c&lt;8*b;c++) {\r\n\u00a0\u00a0\u00a0 for(d=0;d&lt;size;d++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 e=buffer[d];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 e=((e&amp;0x80)&gt;&gt;7) | ((e&amp;0x7f)&lt;&lt;1);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 buffer[d]=e^clockbyte();\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 for(d=0;d&lt;size;d++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 f=(f+buffer[d])%size;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 e=buffer[d];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 buffer[d]=buffer[f];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 buffer[f]=e;\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0 }\r\n}\r\n<\/pre>\n<p>Clockbyte() palauttaa yksinkertaisesti alimmat bitit j\u00e4rjestelm\u00e4n kellosta.<\/p>\n<p>Ressu_genbytes() saa parametreinaan puskurin koon, osoitteen siihen ja kierrosten lukum\u00e4\u00e4r\u00e4n. Se generoi puskuriin satunnaisbittijonon. Rutiini sis\u00e4lt\u00e4\u00e4 kolme kierrosrakennetta, joista c luuppi laskee kierroksia, d laskee puskurin merkkej\u00e4 (alusta loppuun), e:t\u00e4 k\u00e4ytet\u00e4\u00e4n v\u00e4limuuttujana, ja f laskee vaihdettavan merkin paikkaa. F:\u00e4\u00e4n lis\u00e4t\u00e4\u00e4n aina puskurin sis\u00e4lt\u00f6, eli n\u00e4in my\u00f6s kellojono, se vastaa siit\u00e4 ett\u00e4 kun yksikin bitti kellojonossa muuttuu, tulos muuttuu. T\u00e4st\u00e4 tulee periaatteessa mahdollinen ongelma, eli jos kellojono on samanlainen, generaattori generoi samoja bittijonoja uudestaan. N\u00e4ytt\u00e4\u00e4 kuitenkin silt\u00e4 ett\u00e4 kellojonossa on samanlaisia vain noin kilojen kokoisia jaksoja. T\u00e4m\u00e4n perusteella voisi ehk\u00e4 laskea puskurin pituutta. Jatkossa puskurin pituus on m\u00e4\u00e4ritelty 65535 merkiksi.<\/p>\n<p>T\u00e4ss\u00e4 viel\u00e4 muutama apurutiini:<\/p>\n<p>Ressu_genbyte() palauttaa yhden ressu generaattorin arpoman merkin. Ressu_genbyte_limit(int limit) palauttaa yhden haluttua rajaa pienemm\u00e4n merkin (raja on parametrissa limit). ressu_genshort() palauttaa 16 bittisen intin ja ressu_genshort_limit(int limit) palauttaa rajaa pienemm\u00e4n 16 bittisen luvun. ressu_clear() tyhjent\u00e4\u00e4 apurutiinitn ressu_bytes puskurin.<\/p>\n<p>J\u00e4tt\u00e4m\u00e4ll\u00e4 m\u00e4\u00e4rittelem\u00e4tt\u00e4 #define muuttuja RESSU_CLEAR:in voimme est\u00e4\u00e4 puskurin tyhjent\u00e4misen uuden puskurin luonnin yhteydess\u00e4. Jos puskuria ei ole tyhjennetty, voimme alkaa riidell\u00e4 siit\u00e4, kuinka paljon edellisist\u00e4 biteist\u00e4 voidaan arvata uuden puskurin bittej\u00e4. (todellisuudessahan yhteytt\u00e4 edelliseen puskuriin ei ole, puolet biteist\u00e4 vaihtuvat v\u00e4hint\u00e4\u00e4n rounds kertaa).. Toisaalta jos puskuria ei tyhjennet\u00e4, satunnaisuus &#8220;kertyy&#8221; useampien kutsukertojen v\u00e4lill\u00e4.<\/p>\n<p>B muuttuja seuraavan koodin alussa kertoo kuinka monta kierrosta generaattoria ajetaan. Se on nyt 45 ja olen ajatellut sen olevan riitt\u00e4v\u00e4n suuri ettei ongelmia kriittistenk\u00e4\u00e4n satunnaisbittien generoinnissa tule. Samoin tuo puskurin pituus on arvaus, jolla ei pit\u00e4isi tulla ongelmia. Jos esimerkiksi haluat satunnaislukuja shakki peliin tai sudokujen laatimiseen voit ilman muuta valita pienemm\u00e4t luvut. (Esimerkiksi kilon puskuri ja pari kierrosta riitt\u00e4v\u00e4t hyvin perus pelin generaattoriin.) Olen itse tutkinut generaattoria ja tuohon tietoon voi tulla muutoksia. Toisaalta jos noudatat neuvoani ja et k\u00e4yt\u00e4 t\u00e4t\u00e4 generaattoria pelk\u00e4st\u00e4\u00e4n, ei tietenk\u00e4\u00e4n haittaa siirty\u00e4 pienempiin lukuihin.<\/p>\n<pre>#define RESSUBUFLEN 2048\r\nunsigned char ressu_bytes[RESSUBUFLEN];\r\n\r\nint ressu_byte=999999;\r\nint ressu_b = 45;\r\n#define aRESSU_CLEAR 2\r\nunsigned char *file_b = \"libressu1.b\";\r\n\r\nint ressu_genbyte()\r\n{\r\n\u00a0 if(ressu_byte&gt;=ressu_bytes) {\r\n\u00a0\u00a0\u00a0 if(ressu_buffer==NULL)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 ressu_buffersize(ressu_bytes);\r\n#ifdef RESSU_CLEAR\r\n\u00a0\u00a0\u00a0 ressu_clear();\r\n#endif\r\n\u00a0\u00a0\u00a0 ressu_genbytes(ressu_bytes, ressu_buffer,\r\n        ressu_b);\r\n\u00a0\u00a0\u00a0 ressu_byte=0;\r\n\u00a0 }\r\n\u00a0 return(ressu_buffer[ressu_byte++]);\r\n}\r\n\r\nvoid ressu_genbytes_xor(unsigned char *buffer,int size)\r\n{\r\n\u00a0 int c,d;\r\n\r\n\u00a0 for(c=0;c&lt;size;c++)\r\n\u00a0\u00a0\u00a0 buffer[c]^=ressu_genbyte();;\r\n}\r\n\r\nint ressu_genbyte_limit(int limit)\r\n{\r\n\u00a0 int c;\r\n\r\n\u00a0 while((c=ressu_genbyte())&gt;(256\/limit)*limit);\r\n\u00a0 return(c%limit);\r\n}\r\n\r\nint ressu_genshort()\r\n{\r\n\u00a0 return(ressu_genbyte()+256*ressu_genbyte());\r\n}\r\n\r\nint ressu_genshort_limit(int limit)\r\n{\r\n\u00a0 int c;\r\n\r\n\u00a0 while((c=ressu_genshort())&gt;\r\n          (65536\/limit)*limit);\r\n\u00a0 return(c%limit);\r\n}\r\n\r\nvoid ressu_clear()\r\n{\r\n\u00a0 memset(ressu_bytes,0,sizeof(ressu_bytes));\r\n\u00a0 ressu_byte=999999;\r\n}<\/pre>\n<p>Yksi ongelma on m\u00e4\u00e4ritell\u00e4, miten pitk\u00e4 kellojonoo tarvitaan, ett\u00e4 siin\u00e4 on riitt\u00e4v\u00e4sti satunnaisbittej\u00e4 puskuriin. Yksi tapa tarkastella sit\u00e4 on p\u00e4\u00e4tt\u00e4\u00e4 ett\u00e4 yhdess\u00e4 kellon vaihdoksessa on yksi bitti, eli jos yhden vaihdoksen pituus on 20 merkki\u00e4 ja tarvittavien satunnaismerkkien m\u00e4\u00e4r\u00e4 olisi 2048, kaava olisi 2048*8*20. Tulokseksi saataisiin ett\u00e4 b:n arvo olisi sama kuin kellojakson pituus eli 20.<\/p>\n<p>T\u00e4ss\u00e4 ohjelma, joka hakee kellojonon pituuden ja palauttaa sen (lis\u00e4ten 2).<\/p>\n<pre>int ressu_calculate_b()\r\n{\r\n\u00a0 int c,d,ed,count,first,statmax,statlength,b,b2;\r\n\u00a0 unsigned char stats[512];\r\n\r\n\u00a0 while(clockbyte()!=0);\r\n\u00a0 while(clockbyte()==0);\r\n\u00a0 while(clockbyte()!=0);\r\n\r\n\u00a0 for(c=0;c&lt;sizeof(stats);c++)\r\n\u00a0\u00a0\u00a0 stats[c]=0;\r\n\u00a0 first=1;\r\n\u00a0 for(c=0;c&lt;65535;c++) {\r\n\u00a0\u00a0\u00a0 d=clockbyte();\r\n\u00a0\u00a0\u00a0 if(first==1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 ed=d;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 count=1;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 first=0;\r\n\u00a0\u00a0\u00a0 } else if(ed!=d) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 ed=d;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 stats[count]++;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 count=1;\r\n\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 count++;\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0 }\r\n\r\n\u00a0 for(c=0;c&lt;512;c++)\r\n\u00a0\u00a0\u00a0 if(stats[c]&gt;0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\" %d:%2d\",c,stats[c]);\r\n\r\n\u00a0 fprintf(stdout,\"\\n\");\r\n\r\n\u00a0 statmax=0;\r\n\u00a0 statlength=-1;\r\n\u00a0 for(c=0;c&lt;sizeof(stats);c++) {\r\n\u00a0\u00a0\u00a0 if(stats[c]&gt;=statmax) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 statmax=stats[c];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 statlength=c;\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0 }\r\n\u00a0 fprintf(stdout,\"most frequend clockchain size: %d\",statlength);\r\n\u00a0 b2=int_read(file_b);\r\n\u00a0 fprintf(stdout,\", b from file: %d\",b2);\r\n\u00a0 if(b2&gt;=statlength) {\r\n\u00a0\u00a0\u00a0 b=b2;\r\n\u00a0 } else {\r\n\u00a0\u00a0\u00a0 b=statlength;\r\n\u00a0\u00a0\u00a0 int_write(b,file_b);\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", b written to file: %d\",b);\r\n\u00a0 }\r\n\u00a0 fprintf(stdout,\", returned b: %d\\n\",b+2);\r\n\u00a0 fflush(stdout);\r\n\u00a0 \r\n\u00a0 return(b+2);\r\n}\r\n\r\nint int_read(char *filename)\r\n{\r\n\u00a0 int i;\r\n\u00a0 unsigned char buffer[10];\r\n\u00a0 FILE *fp1;\r\n\r\n\u00a0 i=0;\r\n\u00a0 \r\n\u00a0 if((fp1=fopen(filename,\"r\"))!=NULL) {\r\n\u00a0\u00a0\u00a0 fgets(buffer,sizeof(buffer),fp1);\r\n\u00a0\u00a0\u00a0 i=atoi(buffer);\r\n\u00a0\u00a0\u00a0 fclose(fp1);\r\n\u00a0 }\r\n\u00a0 return(i);\r\n}\r\n\r\nvoid int_write(int i, unsigned char *filename)\r\n{\r\n\u00a0 FILE *fp1;\r\n\r\n\u00a0 if((fp1=fopen(filename,\"w\"))!=NULL) {\r\n\u00a0\u00a0\u00a0 fprintf(fp1,\"%d\\n\",i);\r\n\u00a0\u00a0\u00a0 fclose(fp1);\r\n\u00a0 }\r\n}\r\n\r\n<\/pre>\n<p>Jos haluat itse pongata pitki\u00e4 duplikaattimerkkijonoja voit aloittaa sen seuraavalla ohjelmalla:<\/p>\n<pre>#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\n#include \"ressugen.c\"\r\n\r\n#define RESSUBYTES 16384*8\r\n\/\/#define RESSUBYTES 16384*48\r\nunsigned char ressu_bytes[RESSUBYTES];\r\n\r\n#define VERBOSE 2\r\n#define aFAST 2\r\n\r\ntime_t now;\r\n#define HTMLTIMEFORMAT \"%a, %d %b %Y %H:%M:%S GMT\"\r\nunsigned char datestr[128];\r\nchar procname[] = \"Ressutest v0.01\";\r\n\r\nvoid main(int argc,char *argv[])\r\n{\r\n\u00a0 int c,d,e,limit,dup,first0;\r\n\u00a0 int low,high,middle;\r\n\u00a0 time_t now2,now3;\r\n\r\n\u00a0 \r\n\u00a0 now = time(NULL);\r\n\u00a0 strftime(datestr, sizeof(datestr),\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 HTMLTIMEFORMAT, gmtime(&amp;now));\r\n\r\n\u00a0 fprintf(stdout,\"\\n\");\r\n\u00a0 fflush(stdout);\r\n\u00a0 \r\n\u00a0 fprintf(stdout,\"%s\\n%s\\n\\n\",procname,datestr);\r\n\u00a0 fflush(stdout);\r\n\r\n\u00a0 for(;;) {\r\n\u00a0\u00a0\u00a0 for(c=0;c&lt;sizeof(ressu_bytes);c++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 ressu_bytes[c]=clockbyte();\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 now2 = time(NULL);\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 limit=sizeof(ressu_bytes);;\r\n\u00a0\u00a0\u00a0 low=1;\r\n\u00a0\u00a0\u00a0 high=10000;\r\n\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\"limit: %d\",limit);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n\r\n\u00a0\u00a0\u00a0 while(low&lt;=high) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 middle=(low+high)\/2;\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nlimit: %d\",limit);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\", low:%d\",low);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\", high: %d\",high);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\", middle: %d\",middle);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 dup=0;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 for(d=0; d&lt;limit-middle; d++) {\r\n\u00a0\u00a0 \u00a0for(e=d+1; e&lt;limit-middle; e++) {\r\n\u00a0\u00a0 \u00a0\u00a0 if(!memcmp(&amp;ressu_bytes[d],\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0 &amp;ressu_bytes[e],middle)) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0 dup++;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0 e+=middle;\r\n#ifdef FAST\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0 break;\r\n#endif\r\n\u00a0\u00a0 \u00a0\u00a0 }\r\n\u00a0\u00a0 \u00a0}\r\n#ifdef FAST\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(dup)\r\n\u00a0\u00a0 \u00a0break;\r\n#endif\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\", dup: %d\",dup);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(dup) {\r\n\u00a0\u00a0 \u00a0low=middle+1;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0 \u00a0high=middle-1;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", middle: %d\",middle-1);\r\n#endif\r\n\u00a0\u00a0\u00a0 first0=middle-1;\r\n\u00a0\u00a0\u00a0 dup=0;\r\n\u00a0\u00a0\u00a0 for(d=0;d&lt;limit-(middle-1);d++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 for(e=d+1;e&lt;limit-(middle-1);e++) {\r\n\u00a0\u00a0 \u00a0if(!memcmp(&amp;ressu_bytes[d],\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 &amp;ressu_bytes[e],middle-1)) {\r\n\u00a0\u00a0 \u00a0\u00a0 dup++;\r\n\u00a0\u00a0 \u00a0\u00a0 e+=middle;\r\n#ifdef FAST\r\n\u00a0\u00a0 \u00a0\u00a0 break;\r\n#endif\u00a0\u00a0 \u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n#ifdef FAST\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(dup)\r\n\u00a0\u00a0 \u00a0break;\r\n#endif\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 if(dup!=0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 first0++;\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", dup: %d\",dup); \u00a0\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", middle: %d\",middle);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n\u00a0\u00a0\u00a0 dup=0;\r\n\u00a0\u00a0\u00a0 for(d=0;d&lt;limit-middle;d++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 for(e=d+1;e&lt;limit-middle;e++) {\r\n\u00a0\u00a0 \u00a0if(!memcmp(&amp;ressu_bytes[d],\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 &amp;ressu_bytes[e],middle)) {\r\n\u00a0\u00a0 \u00a0\u00a0 dup++;\r\n\u00a0\u00a0 \u00a0\u00a0 e+=middle;\r\n#ifdef FAST\r\n\u00a0\u00a0 \u00a0\u00a0 break;\r\n#endif\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n#ifdef FAST\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(dup)\r\n\u00a0\u00a0 \u00a0break;\r\n#endif\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 if(dup!=0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 first0++;\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", dup2: %d\",dup);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", middle: %d\",middle+1);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n\u00a0\u00a0\u00a0 dup=0;\r\n\u00a0\u00a0\u00a0 for(d=0;d&lt;limit-(middle+1);d++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 for(e=d+1;e&lt;limit-(middle+1);e++) {\r\n\u00a0\u00a0 \u00a0if(!memcmp(&amp;ressu_bytes[d],\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 &amp;ressu_bytes[e],middle+1)) {\r\n\u00a0\u00a0 \u00a0\u00a0 dup++;\r\n\u00a0\u00a0 \u00a0\u00a0 e+=middle;\r\n#ifdef FAST\r\n\u00a0\u00a0 \u00a0\u00a0 break;\r\n#endif\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n#ifdef FAST\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(dup)\r\n\u00a0\u00a0 \u00a0break;\r\n#endif\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 if(dup!=0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 first0++;\r\n\u00a0\u00a0\u00a0 now3 = time(NULL);\r\n#ifdef VERBOSE\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", dup3: %d\",dup);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n#endif\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", first0: %d\",first0);\r\n\r\n\u00a0\u00a0\u00a0 int time;\r\n\r\n\u00a0\u00a0\u00a0 time=now3-now2;\r\n\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\", took \");\r\n\u00a0\u00a0\u00a0 if((time\/60)&gt;0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\"%d minutes, \",time\/60);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 time%=60;\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\"%d seconds.\\n\",time);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n\u00a0 }\r\n}<\/pre>\n<p>Seuraavassa mallitulokset edellisest\u00e4 ohjelmasta: ensimm\u00e4isess\u00e4 listassa VERBOSE ei ole m\u00e4\u00e4ritelty. Toisessa ja kolmannessa VERBOSE on m\u00e4\u00e4ritelty. Toisessa listassa FAST on m\u00e4\u00e4ritelty, kolmannessa FAST ei ole m\u00e4\u00e4ritelty. Limit on puskurin koko. Low, high ja middle ovat bin\u00e4\u00e4rihaun muuttujat. Dup kertoo onko duplikaatteja. Dup on 0 tai 1, jos FAST on m\u00e4\u00e4ritelty, muuten tuplamerkkijonojen\u00a0lukum\u00e4\u00e4r\u00e4. First0 \u00a0on ensimm\u00e4inen pituus, jolla ei ole tuplamerkkijonoja.<\/p>\n<pre>limit: 131072, first0: 1818, took 17 minutes, 10 seconds.\r\nlimit: 131072, first0: 1618, took 13 minutes, 23 seconds.\r\nlimit: 131072, first0: 2790, took 15 minutes, 16 seconds.\r\nlimit: 131072, first0: 2616, took 11 minutes, 21 seconds.\r\nlimit: 131072, first0: 2598, took 16 minutes, 35 seconds.\r\n\r\nlimit: 131072, low:1, high: 10000, middle: 5000, dup: 0\r\nlimit: 131072, low:1, high: 4999, middle: 2500, dup: 0\r\nlimit: 131072, low:1, high: 2499, middle: 1250, dup: 1\r\nlimit: 131072, low:1251, high: 2499, middle: 1875, dup: 1\r\nlimit: 131072, low:1876, high: 2499, middle: 2187, dup: 0\r\nlimit: 131072, low:1876, high: 2186, middle: 2031, dup: 1\r\nlimit: 131072, low:2032, high: 2186, middle: 2109, dup: 1\r\nlimit: 131072, low:2110, high: 2186, middle: 2148, dup: 0\r\nlimit: 131072, low:2110, high: 2147, middle: 2128, dup: 1\r\nlimit: 131072, low:2129, high: 2147, middle: 2138, dup: 1\r\nlimit: 131072, low:2139, high: 2147, middle: 2143, dup: 1\r\nlimit: 131072, low:2144, high: 2147, middle: 2145, dup: 0\r\nlimit: 131072, low:2144, high: 2144, middle: 2144, dup: 1, middle: 2143, dup: 1, middle: 2144, dup2: 1, middle: 2145, dup3: 0, first0: 2145, took 13 minutes, 54 seconds.\r\nlimit: 131072\r\nlimit: 131072, low:1, high: 10000, middle: 5000, dup: 0\r\nlimit: 131072, low:1, high: 4999, middle: 2500, dup: 0\r\nlimit: 131072, low:1, high: 2499, middle: 1250, dup: 1\r\nlimit: 131072, low:1251, high: 2499, middle: 1875, dup: 0\r\nlimit: 131072, low:1251, high: 1874, middle: 1562, dup: 1\r\nlimit: 131072, low:1563, high: 1874, middle: 1718, dup: 0\r\nlimit: 131072, low:1563, high: 1717, middle: 1640, dup: 1\r\nlimit: 131072, low:1641, high: 1717, middle: 1679, dup: 0\r\nlimit: 131072, low:1641, high: 1678, middle: 1659, dup: 1\r\nlimit: 131072, low:1660, high: 1678, middle: 1669, dup: 0\r\nlimit: 131072, low:1660, high: 1668, middle: 1664, dup: 0\r\nlimit: 131072, low:1660, high: 1663, middle: 1661, dup: 1\r\nlimit: 131072, low:1662, high: 1663, middle: 1662, dup: 1\r\nlimit: 131072, low:1663, high: 1663, middle: 1663, dup: 1, middle: 1662, dup: 1, middle: 1663, dup2: 1, middle: 1664, dup3: 0, first0: 1664, took 16 minutes, 0 seconds.\r\n\r\nlimit: 131072, low:1, high: 10000, middle: 5000, dup: 0\r\nlimit: 131072, low:1, high: 4999, middle: 2500, dup: 0\r\nlimit: 131072, low:1, high: 2499, middle: 1250, dup: 666\r\nlimit: 131072, low:1251, high: 2499, middle: 1875, dup: 0\r\nlimit: 131072, low:1251, high: 1874, middle: 1562, dup: 0\r\nlimit: 131072, low:1251, high: 1561, middle: 1406, dup: 252\r\nlimit: 131072, low:1407, high: 1561, middle: 1484, dup: 96\r\nlimit: 131072, low:1485, high: 1561, middle: 1523, dup: 34\r\nlimit: 131072, low:1524, high: 1561, middle: 1542, dup: 15\r\nlimit: 131072, low:1543, high: 1561, middle: 1552, dup: 5\r\nlimit: 131072, low:1553, high: 1561, middle: 1557, dup: 0\r\nlimit: 131072, low:1553, high: 1556, middle: 1554, dup: 3\r\nlimit: 131072, low:1555, high: 1556, middle: 1555, dup: 2\r\nlimit: 131072, low:1556, high: 1556, middle: 1556, dup: 1, middle: 1555, dup: 2, middle: 1556, dup2: 1, middle: 1557, dup3: 0, first0: 1557, took 25 minutes, 46 seconds.\r\nlimit: 131072\r\nlimit: 131072, low:1, high: 10000, middle: 5000, dup: 0\r\nlimit: 131072, low:1, high: 4999, middle: 2500, dup: 469\r\nlimit: 131072, low:2501, high: 4999, middle: 3750, dup: 0\r\nlimit: 131072, low:2501, high: 3749, middle: 3125, dup: 0\r\nlimit: 131072, low:2501, high: 3124, middle: 2812, dup: 102\r\nlimit: 131072, low:2813, high: 3124, middle: 2968, dup: 0\r\nlimit: 131072, low:2813, high: 2967, middle: 2890, dup: 24\r\nlimit: 131072, low:2891, high: 2967, middle: 2929, dup: 0\r\nlimit: 131072, low:2891, high: 2928, middle: 2909, dup: 5\r\nlimit: 131072, low:2910, high: 2928, middle: 2919, dup: 0\r\nlimit: 131072, low:2910, high: 2918, middle: 2914, dup: 0\r\nlimit: 131072, low:2910, high: 2913, middle: 2911, dup: 3\r\nlimit: 131072, low:2912, high: 2913, middle: 2912, dup: 2\r\nlimit: 131072, low:2913, high: 2913, middle: 2913, dup: 1, middle: 2912, dup: 2, middle: 2913, dup2: 1, middle: 2914, dup3: 0, first0: 2914, took 29 minutes, 26 seconds.\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e4ss\u00e4 oikeastaan ensimm\u00e4inen &#8220;virallinen&#8221; julkaisu Ressu-satunnaislukugenetaattorin versiosta 1.0. Edit: muokattu julkaisun j\u00e4lkeisten viikkojen aikana. Satunnaislukugeneraattorihan koostuu kahdesta funktiosta, clockbyte(), joka palauttaa kellojonon seuraavan merkin, ja ressu_genbytes(), joka on varsinainen generaattori. Ensimm\u00e4inen kierros genbytes() rutiinista vaihtaa jokaisen merkin bittien j\u00e4rjestyst\u00e4 ja summaa merkkiin seuraavan kellojonon merkin. Ajatuksena on ett\u00e4 jokainen tuloksena tulevan puskurin bitti koskee kaikkia&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=529\">Continue reading <span class=\"screen-reader-text\">Ressu versio 1<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/529"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=529"}],"version-history":[{"count":56,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/529\/revisions"}],"predecessor-version":[{"id":592,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/529\/revisions\/592"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}