{"id":1703,"date":"2021-07-07T13:01:22","date_gmt":"2021-07-07T11:01:22","guid":{"rendered":"https:\/\/moijari.com\/?p=1703"},"modified":"2023-02-22T13:13:04","modified_gmt":"2023-02-22T11:13:04","slug":"ressu-2-2-pari-korjausta-sample-optio-ja-paaohjelman-palastelua","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=1703","title":{"rendered":"Ressu 2.2 pari korjausta, &#8211;sample optio ja p\u00e4\u00e4ohjelman palastelua"},"content":{"rendered":"\n<p>Aiemmasta versiosta on korjattu pari bugia. Ensimm\u00e4isess\u00e4 variaatioissa on vain pieni\u00e4 ketjuja, ja 1,6 rajaa pienten ja suurien ketjujen v\u00e4lill\u00e4 ei l\u00f6ydy. T\u00e4ll\u00f6in lim1 ja lim2 kent\u00e4t t\u00e4ytettiin joskus -1:ll\u00e4. Tietue ensimm\u00e4isest\u00e4 bugista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>round: 0 1:1 2:1 3:3 5:2 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:4 15:6 lim1:6 lim2:-1 clockbytes:244 rndbits:25<\/code><\/pre>\n\n\n\n<p>Toisessa bugissa on eripituisia variaatioita aina 1 kappaletta: jolloin isojen ketjujen ensimm\u00e4inen p\u00e4\u00e4tyy teoreettisiin bitteihin ja _genbytes rutiinista palataan liian nopeasti. T\u00e4ss\u00e4 esimerkki vanhasta ohjelmasta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>round: 1 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 12:1 14:1161 15:1096 lim1:1161 lim2:1161 clockbytes:32761 rndbits:1107\nround: 1 1:1 2:1 3:1 5:1 6:1 7:1 8:1 9:1 10:1 12:1 13:1 14:1158 15:1099 lim1:1158 lim2:1158 clockbytes:32773 rndbits:1110\nround: 1 1:1 2:1 4:1 5:1 8:1 9:1 10:1 11:1 13:1 14:1168 15:1090 lim1:1168 lim2:1168 clockbytes:32765 rndbits:1099<\/code><\/pre>\n\n\n\n<p>Muutoksissa on &#8211;sample optio, jolla voidaan tulostaa 8gb:n pituinen mallitiedosto, jolla voidaan testata satunnaisuutta esimerkiksi Dieharder ohjelmalla.<\/p>\n\n\n\n<p>Lis\u00e4ksi p\u00e4\u00e4ohjelmasta on palasteltu useampaan kertaan k\u00e4ytettyj\u00e4 rutiineja omiksi funktioikseen.<\/p>\n\n\n\n<p>Bugikorjaukset ovat lim=0 rivill\u00e4, if(prevbyte==-1 &amp;&amp; f!=-1) rivill\u00e4 ja if(f!=-1) rivill\u00e4.<\/p>\n\n\n\n<p>T\u00e4ss\u00e4 toisaalta koodikorjaukset edellisist\u00e4 bugeista ja muista muutoksista. T\u00e4ss\u00e4 aluksi koodi varsinaisesta korjatusta generaattorista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}\n\nvoid ressu_genbytes_fast(int size, unsigned char *buffer)\n{\n  int c, d, e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  for(c=0; c&lt;8; c++) {\n    for(d=0; d&lt;size; d++) {\n      e = buffer&#91;d];\n      e = ((e&amp;0x80)>>7) | ((e&amp;0x7f)&lt;&lt;1); \/\/ rotate left 1\n      \/\/e=((e&amp;0xe0)>>5) | ((e&amp;0x1f)&lt;&lt;3); \/\/ rotate left 3\n      \/\/e=((e&amp;0xfe)>>1) | ((e&amp;0x1)&lt;&lt;7);  \/\/ rotate right 1\n      byte = ressu_clockbyte();\n      if(prevbyte==-1)\n\tprevbyte=byte;\n      buffer&#91;d] = e^byte;\n      if(prevbyte!=byte) {\n\tperiods&#91;count]++;\n\tclockbytes+=count;\n\tcount=0;\n\tprevbyte=byte;\n      }\n      count++;\n    }\n    for(d=0; d&lt;size; d++) {\n      f = (f+buffer&#91;d])%size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n  }\n}\n\nvoid ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c,d,e;\n  static int ressut_first=1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  static unsigned char ressut&#91;RESSUT_BYTES];\n  \n  for(c=0; c&lt;size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut,0,ressut_bytes);\n\tressut_first=0;\n      }\n\n      clockbytes=0;\n      for(d=0;d&lt;1024;d++)\n\tperiods&#91;d]=0;\n      \n      int rndbits=0;\n      int lim, lim1, lim2;\n\n      for(d=0; rndbits&lt;ressu_bits_needed ||\n\t  d&lt;RESSU_MIN_ROUNDS ||\n\t  clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n\tressu_genbytes_fast(ressut_bytes,ressut);\n\n\tlim=0;\n\t\n\tint ok=1, f, prevf=-1;\n\n\twhile(ok==1) {\n\t  ok=0;\n\t  f=-1;\n\t  for(e=0;e&lt;1024;e++) {\n\t    if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f)) {\n\t      f=periods&#91;e];\n\t    }\n\t  }\n\t  if((prevf==-1 &amp;&amp; f!=-1)|| (f!=-1 &amp;&amp; f&lt;=(double)prevf*1.6)) {\n\t    lim=f;\n\t    prevf=f;\n\t    ok=1;\n\t  }\n\t} \/\/ while(ok==1)\n\n\tlim1=lim;\n\t\n\t\/\/ find next greater than lim\n\n\tf=-1;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f))\n\t    f=periods&#91;e];\n\t}\n\tif(f!=-1)\n\t  lim=f;\n\n\tlim2=lim;\n\t\n\tint prev_rndbits=rndbits;\n\n\trndbits=0;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>0 &amp;&amp; periods&#91;e]&lt;lim) {\n\t    rndbits+=periods&#91;e];\n\t  }\n\t}\n\n\tif(rndbits==0 || prev_rndbits == rndbits) { \/\/ restart\n\t  clockbytes=0;\n\t  for(e=0;e&lt;1024;e++)\n\t    periods&#91;e]=0;\n\t  rndbits=0;\n\t}\n\t\n      } \/\/ for(d=0;\n      if(stats) {\n\tfprintf(stdout,\"round: %d\",d);\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>0)\n\t    fprintf(stdout,\" %d:%lu\",e,periods&#91;e]);\n\t}\n\tfprintf(stdout,\" lim1:%d\",lim1);\n\tfprintf(stdout,\" lim2:%d\",lim2);\n\tfprintf(stdout,\" clockbytes:%ld\",clockbytes);\n\tfprintf(stdout,\" rndbits:%d\",rndbits);\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n      }\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n  genbytes+=size;\n}<\/code><\/pre>\n\n\n\n<p>P\u00e4\u00e4ohjelmasta palastellut rutiinit: line_number_length() p\u00e4\u00e4si ulkoistettujen seuraan vaikka sill\u00e4 oli vain yksi kutsukohta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int line_number_length()\n{\n  int c;\n  out_word(sizeof(linenobuf),linenobuf,\"0123456789\",lines-1);\n  c=strlen(linenobuf);\n  if(c&lt;5)\n    c=5;\n  return(c);\n}\n\nvoid print_line_number()\n{\n  unsigned char linenobuf&#91;1024];\n  \n  if(pchars==0 &amp;&amp; !quiet &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*d\",plinesdigits,plines);\n    fprintf(stdout,\"%s\",linenobuf);\n    pchars +=strlen(linenobuf);\n    fprintf(stdout,\" \");\n    pchars++;\n  }\n}\n\nvoid print_spaces()\n{\n  if(sspace &amp;&amp; pchars&gt;0 &amp;&amp; !quiet) {\n    if(sspace==3 &amp;&amp; pwords%2==0) {\n      fprintf(stdout,\" \");\n      pchars++;\n    }\n    fprintf(stdout,\" \");\n    pchars++;\n  }\n}\n\nvoid print_word(unsigned char *buf)\n{\n  if(size!=0) {\n    if(!quiet)\n      fprintf(stdout,\"%*s\",size,buf);\n    pchars += size;\n    pwords++;\n  } else {\n    if(!quiet)\n      fprintf(stdout,\"%s\",buf);\n    pchars += strlen(wordbuf);\n    pwords++;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Ja palastelun takia muutetut palat p\u00e4\u00e4ohjelmasta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  for(;;) {\n\n    if(!sort) { \/\/ also lotto\n\n      pchars=0;\n      pwords=0;\n\n      while(pwords&lt;linew) {\n\treadword(wordbuf);\n\n\t\/\/ in beginning of line, print line number\n\n\tprint_line_number();\n\t\n\t\/\/ want to print spaces between \"words\"?\n\n\tprint_spaces();\n\t\n\t\/\/ print word\n\n\tprint_word(wordbuf);\n\n      } \/\/ while(pwords&lt;linew) {\n    } else { \/\/ if(!sort)\n\n      pchars=0;\n      pwords=0;\n      \n      line_clear(&amp;linecnt,&amp;line);\n\n      \/\/ fetch and save words on this row\n      while(pwords&lt;linew) {\n\treadword(wordbuf);\n\n\tif(line_add_string_sort(&amp;linecnt,&amp;line,wordbuf)) {\n\t  pwords++;\n\t}\n      } \/\/ while(pwords&lt;linew) {\n\n      pchars=0;\n      pwords=0;\n\n      \/\/ print words on this row\n      while(pwords&lt;linew) {\n\n\tline_get_string(sizeof(wordbuf),wordbuf,pwords,line);\n\n\t\/\/ in beginning of line, print line number\n\n\tprint_line_number();\n\t\n\t\/\/ want to print spaces between \"words\"?\n\t\n\tprint_spaces();\n\n\t\/\/ print word\n\t\n\tprint_word(wordbuf);\n\n      } \/\/ while(pwords&lt;linew) {\n    } \/\/ if(!sort)\n\n    \/\/ line full?\n    \n    if(!quiet) {\n      fprintf(stdout,\"\\n\");\n    }\n    plines++;\n    if(sspace==3 &amp;&amp; plines&lt;lines &amp;&amp; plines%5==0)\n      fprintf(stdout,\"\\n\");\n\n    \/\/ all needed lines printed?\n\n    if(plines &gt;= lines)\n      break;\n\n  } \/\/ for(;;)<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty sample optio, jolla voidaan tulostaa newressusample.rnd tiedosto satunnaisbittien testaamiseen vaikka dieharder ohjelmalla. &#8211;sample parametrin k\u00e4ytt\u00e4m\u00e4t palat parametrien k\u00e4sittelyss\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--lotto\",argv&#91;c])) {\n\tsort=!sort;\n\tif(sspace==0)\n\t  sspace=1;\n\t\/\/sort=1;\n\t\/\/unique=1;\n\n      } else if(!strcmp(\"--sample\",argv&#91;c])) {\n\tsample=!sample;\n\t\n      } else if(!strcmp(\"--copyright\",argv&#91;c]) ||\n\t !strcmp(\"--version\",argv&#91;c])) {\n\tfprintf(stderr,\"%s\",programname);\n\tfprintf(stderr,\", %s\",copyright);\n\tfprintf(stderr,\"\\n\\n\");\n\thelp=1;\n\t\n      <\/code><\/pre>\n\n\n\n<p>&#8211;sample esimerkkitiedoston tulostus: tiedoston koko on t\u00e4ss\u00e4 8GB, eli 1048576*4096*2<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if(sample) {\n    FILE *fp1;\n    unsigned char buffer&#91;4096];\n\n    fp1=fopen(\"newressusample.rnd\",\"w\");\n    for(c=0;c&lt;1048576;c++) {\n      ressu_genbytes(sizeof(buffer),buffer);\n      fwrite(buffer,1,sizeof(buffer),fp1);\n      ressu_genbytes(sizeof(buffer),buffer);\n      fwrite(buffer,1,sizeof(buffer),fp1);\n    }\n    fclose(fp1);\n    exit(0);\n  }<\/code><\/pre>\n\n\n\n<p>Voit tulostaa samplen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ newressu --sample<\/code><\/pre>\n\n\n\n<p>komennolla ja dieharder ohjelmaa voit ajaa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ dieharder -a -g 201 -f newressusample.rnd<\/code><\/pre>\n\n\n\n<p>komennolla.<\/p>\n\n\n\n<p>T\u00e4ss\u00e4 sorsa kokonaisuudessaan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;unistd.h>\n#include &lt;malloc.h>\n\n#include &lt;string.h>\n#include &lt;ctype.h>\n#include &lt;math.h>\n#include &lt;sys\/time.h>\n\nunsigned char *procname;\nstatic char *programname = \"newressu version 2.2 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2013-2021 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nunsigned long periods&#91;1024];\nunsigned long genbytes=0;\nunsigned long clockbytes=0;\n\n#define RESSUT_BYTES 4096\n#define RESSU_BITS_NEEDED 128\n#define RESSU_MIN_ROUNDS 2\n#define RESSU_MIN_CLOCKBYTES 16384+1024\n\nint ressu_bits_needed=RESSU_BITS_NEEDED;\nint ressut_bytes = RESSUT_BYTES;\n\nint stats=0;\n\nunsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}\n\nvoid ressu_genbytes_fast(int size, unsigned char *buffer)\n{\n  int c, d, e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  for(c=0; c&lt;8; c++) {\n    for(d=0; d&lt;size; d++) {\n      e = buffer&#91;d];\n      e = ((e&amp;0x80)>>7) | ((e&amp;0x7f)&lt;&lt;1); \/\/ rotate left 1\n      \/\/e=((e&amp;0xe0)>>5) | ((e&amp;0x1f)&lt;&lt;3); \/\/ rotate left 3\n      \/\/e=((e&amp;0xfe)>>1) | ((e&amp;0x1)&lt;&lt;7);  \/\/ rotate right 1\n      byte = ressu_clockbyte();\n      if(prevbyte==-1)\n\tprevbyte=byte;\n      buffer&#91;d] = e^byte;\n      if(prevbyte!=byte) {\n\tperiods&#91;count]++;\n\tclockbytes+=count;\n\tcount=0;\n\tprevbyte=byte;\n      }\n      count++;\n    }\n    for(d=0; d&lt;size; d++) {\n      f = (f+buffer&#91;d])%size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n  }\n}\n\nvoid ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c,d,e;\n  static int ressut_first=1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  static unsigned char ressut&#91;RESSUT_BYTES];\n  \n  for(c=0; c&lt;size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut,0,ressut_bytes);\n\tressut_first=0;\n      }\n\n      clockbytes=0;\n      for(d=0;d&lt;1024;d++)\n\tperiods&#91;d]=0;\n      \n      int rndbits=0;\n      int lim, lim1, lim2;\n\n      for(d=0; rndbits&lt;ressu_bits_needed ||\n\t  d&lt;RESSU_MIN_ROUNDS ||\n\t  clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n\tressu_genbytes_fast(ressut_bytes,ressut);\n\n\tlim=0;\n\t\n\tint ok=1, f, prevf=-1;\n\n\twhile(ok==1) {\n\t  ok=0;\n\t  f=-1;\n\t  for(e=0;e&lt;1024;e++) {\n\t    if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f)) {\n\t      f=periods&#91;e];\n\t    }\n\t  }\n\t  if((prevf==-1 &amp;&amp; f!=-1)|| (f!=-1 &amp;&amp; f&lt;=(double)prevf*1.6)) {\n\t    lim=f;\n\t    prevf=f;\n\t    ok=1;\n\t  }\n\t} \/\/ while(ok==1)\n\n\tlim1=lim;\n\t\n\t\/\/ find next greater than lim\n\n\tf=-1;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f))\n\t    f=periods&#91;e];\n\t}\n\tif(f!=-1)\n\t  lim=f;\n\n\tlim2=lim;\n\t\n\tint prev_rndbits=rndbits;\n\n\trndbits=0;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>0 &amp;&amp; periods&#91;e]&lt;lim) {\n\t    rndbits+=periods&#91;e];\n\t  }\n\t}\n\n\tif(rndbits==0 || prev_rndbits == rndbits) { \/\/ restart\n\t  clockbytes=0;\n\t  for(e=0;e&lt;1024;e++)\n\t    periods&#91;e]=0;\n\t  rndbits=0;\n\t}\n\t\n      } \/\/ for(d=0;\n      if(stats) {\n\tfprintf(stdout,\"round: %d\",d);\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>0)\n\t    fprintf(stdout,\" %d:%lu\",e,periods&#91;e]);\n\t}\n\tfprintf(stdout,\" lim1:%d\",lim1);\n\tfprintf(stdout,\" lim2:%d\",lim2);\n\tfprintf(stdout,\" clockbytes:%ld\",clockbytes);\n\tfprintf(stdout,\" rndbits:%d\",rndbits);\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n      }\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n  genbytes+=size;\n}\n\n#define DEBUG4 2\n\n#ifdef DEBUG4\nunsigned char cc&#91;256*1048576]; \/\/ clock_chain\nunsigned char *ccp;\nint cc_bytes;\n#endif\n\nunsigned char ressu_clockbyte_debug() \/* JariK 2013 *\/\n{\n  unsigned char c;\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  c=tv.tv_usec &amp; 0xff;\n#ifdef DEBUG4\n  if(cc_bytes&lt;sizeof(cc)) {\n    *ccp++ = c;\n    cc_bytes++;\n  }\n#endif\n  return(c);\n}\n\nvoid ressu_genbytes_fast_debug(int size, unsigned char *buffer)\n{\n  int c, d, e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  for(c=0; c&lt;8; c++) {\n    for(d=0; d&lt;size; d++) {\n      e = buffer&#91;d];\n      e = ((e&amp;0x80)>>7) | ((e&amp;0x7f)&lt;&lt;1); \/\/ rotate left 1\n      \/\/e=((e&amp;0xe0)>>5) | ((e&amp;0x1f)&lt;&lt;3); \/\/ rotate left 3\n      \/\/e=((e&amp;0xfe)>>1) | ((e&amp;0x1)&lt;&lt;7);  \/\/ rotate right 1\n      byte = ressu_clockbyte_debug();\n      if(prevbyte==-1)\n\tprevbyte=byte;\n      buffer&#91;d] = e^byte;\n      if(prevbyte!=byte) {\n\tperiods&#91;count]++;\n\tclockbytes+=count;\n\tcount=0;\n\tprevbyte=byte;\n      }\n      count++;\n    }\n    for(d=0; d&lt;size; d++) {\n      f = (f+buffer&#91;d])%size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n  }\n}\n\nvoid ressu_genbytes_debug(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c,d,e;\n  static int ressut_first=1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  static unsigned char ressut&#91;RESSUT_BYTES];\n  \n  for(c=0; c&lt;size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut,0,ressut_bytes);\n\tressut_first=0;\n      }\n\n      clockbytes=0;\n      for(d=0;d&lt;1024;d++)\n\tperiods&#91;d]=0;\n      \n#ifdef DEBUG4\n      ccp=cc;\n      cc_bytes=0;\n\n      while(ressu_clockbyte_debug()!=0);\n      while(ressu_clockbyte_debug()==0);\n\n      ccp=cc;\n      cc_bytes=0;\n#endif\n\n      int rndbits=0, rounds=0;\n      int lim, lim1, lim2;\n\n      for(d=0; rndbits&lt;ressu_bits_needed ||\n\t  d&lt;RESSU_MIN_ROUNDS; d++) {\n\n\trounds++;\n\t\n\tressu_genbytes_fast_debug(ressut_bytes,ressut);\n\n\tlim=0;\n\t\n\tint ok=1, f, prevf=-1;\n\n\twhile(ok==1) {\n\t  ok=0;\n\t  f=-1;\n\t  for(e=0;e&lt;1024;e++) {\n\t    if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f)) {\n\t      f=periods&#91;e];\n\t    }\n\t  }\n\t  if((prevf==-1 &amp;&amp; f!=-1)|| (f!=-1 &amp;&amp; f&lt;=(double)prevf*1.6)) {\n\t    lim=f;\n\t    prevf=f;\n\t    ok=1;\n\t  }\n\t} \/\/ while(ok==1)\n\n\tlim1=lim;\n\n\t\/\/ find next greater than lim\n\n\tf=-1;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>lim &amp;&amp; (f==-1 || periods&#91;e]&lt;f))\n\t    f=periods&#91;e];\n\t}\n\tif(f!=-1)\n\t  lim=f;\n\n\tlim2=lim;\n\t\n\tint prev_rndbits=rndbits;\n\n\trndbits=0;\n\tfor(e=0;e&lt;1024;e++) {\n\t  if(periods&#91;e]>0 &amp;&amp; periods&#91;e]&lt;lim) {\n\t    rndbits+=periods&#91;e];\n\t  }\n\t}\n\n\tif(rndbits==0 || prev_rndbits == rndbits) { \/\/ restart\n\t  clockbytes=0;\n\t  for(e=0;e&lt;1024;e++)\n\t    periods&#91;e]=0;\n\t  ccp=cc;\n\t  cc_bytes=0;\n\t  rndbits=0;\n\t}\n      } \/\/ for(d=0;\n\n#ifdef DEBUG4\n      FILE *fp1;\n      if((fp1=fopen(\"newressu.deb\",\"a\"))!=NULL) {\n\t\/\/if(lim1==-1 || lim2==-1 || lim1==lim2) {\n\tfor(d=0;d&lt;32;d++)\n\t  fprintf(fp1,\"%02x\",ressut&#91;d]);\n\n\tfprintf(fp1,\", ressut_bytes: %d\",ressut_bytes);\n\tfprintf(fp1,\", ressu_bits_needed: %d\",ressu_bits_needed);\n\tfprintf(fp1,\", ressu_min_rounds: %d\",RESSU_MIN_ROUNDS);\n\n\tfprintf(fp1,\", clockbytes: %ld\",clockbytes);\n\t\n\tunsigned long total=0;\t\n\tfprintf(fp1,\", fluctuations:\");\n\tfor(d=0;d&lt;1024;d++) {\n\t  if(periods&#91;d]!=0) {\n\t    fprintf(fp1,\" %d:%lu\",d,periods&#91;d]);\n\t    total+=(periods&#91;d]*d);\n\t  }\n\t}\n\tfprintf(fp1,\", total: %lu\",total);\n\tfprintf(fp1,\", limit1: %d\",lim1);\n\tfprintf(fp1,\", limit2: %d\",lim2);\n\tfprintf(fp1,\", limit: %d\",lim);\n\n\tfprintf(fp1,\", skipped:\");\n\tfor(d=0;d&lt;1024;d++) {\n\t  if(periods&#91;d]>=lim) {\n\t    fprintf(fp1,\" %d:%lu\",d,periods&#91;d]);\n\t  }\n\t}\n\t\n\tfprintf(fp1,\", counted:\");\n\tfor(d=0;d&lt;1024;d++) {\n\t  if(periods&#91;d]>0 &amp;&amp; periods&#91;d]&lt;lim) {\n\t    fprintf(fp1,\" %d:%lu\",d,periods&#91;d]);\n\t  }\n\t}\t\n\tfprintf(fp1,\", rndbits: %d\",rndbits);\n\tfprintf(fp1,\", rounds: %d\",rounds);\n\n\tint prevbyte=-1, count=0, count2=0;\n\tunsigned char byte, small=-1;\n\n\tfprintf(fp1,\", small chains:\");\n\tfor(d=0;d&lt;cc_bytes;d++) {\n\t  byte=cc&#91;d];\n\t  if(prevbyte==-1) {\n\t    prevbyte=byte;\n\t    count=1;\n\t  }\n\t  if(prevbyte!=byte) {\n\t    if(periods&#91;count]>=lim) {\n\t      if(small==1 || small==-1)\n\t\tfprintf(fp1,\" *\");\n\t      small=0;\n\t    } else small=1;\n\t    if(small) {\n\t      fprintf(fp1,\" %d\",count);\n\t      count2++;\n\t    }\n\t    count=0;\n\t    prevbyte=byte;\n\t  }\n\t  count++;\n\t}\n\tif(small) {\n\t  fprintf(fp1,\" %d\",count);\n\t  count2++;\n\t}\n\tfprintf(fp1,\", count: %d\",count2);\n\n\tfprintf(fp1,\"\\n\");\n\tfflush(fp1);\n\t\/\/}\n\tfclose(fp1);\n      } \/\/ if((fp1=fopen\n#endif\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n  genbytes+=size;\n}\n\nstatic void readfile_xor(int len,\n    unsigned char *buf,\n    unsigned char *filename)\n{\n  int c, n, n2;\n  unsigned char temp&#91;64];\n  FILE *fp1;\n\n  if((fp1 = fopen(filename, \"rb\"))\n      != NULL) {\n    while(len != 0) {\n      n = (len &lt; sizeof(temp)) ?\n          len : sizeof(temp);\n      n2=fread(temp, 1, n, fp1);\n      for(c = 0; c &lt; n2; c++)\n        buf&#91;c] ^= temp&#91;c];\n      len -= n2;\n      buf += n2;\n    }\n    fclose(fp1);\n  }\n}\n\nint input=0;\n\n#define GENT_SIZE 2048\n#define aUSE_RANDOM 2\n\n#define aDEBUG9 2\n\nchar *randomgen&#91;] = { \"ressu\", \"debug\",\"fast\",\"single\",\"4\",\"5\",\"6\",\"7\",\"urandom\",\"random\" };\n\nint ressu_genbyte()\n{\n  int c;\n  static unsigned char gent&#91;GENT_SIZE];\n  static unsigned int gent_pos=0; \/\/ Little bug\n  unsigned char ch;\n\n  if(input==0) { \/\/ ressu prod\n    ressu_genbytes(sizeof(ch), &amp;ch);\n  } else if(input==1) { \/\/ ressu debug\n    ressu_genbytes_debug(sizeof(ch), &amp;ch);\n  } else {\n    if(gent_pos==0) {\n      if(input==2) { \/\/ ressu_fast\n\tclockbytes=0;\n\tfor(c=0; c&lt;RESSU_MIN_ROUNDS ||\n\t  clockbytes &lt; RESSU_MIN_CLOCKBYTES;c++) {\n\t  ressu_genbytes_fast(sizeof(gent),gent);\n\t}\n      } else if(input==3) { \/\/ ressu_single\n\tressu_genbytes_fast(sizeof(gent),gent);\n      } else if(input==8) { \/\/ urandom\n\treadfile_xor(sizeof(gent),gent,\"\/dev\/urandom\");\n#ifdef USE_RANDOM\n      } else if(input==9) { \/\/ random\n\treadfile_xor(sizeof(gent),gent,\"\/dev\/random\");\n#endif\n      }\n    } \/\/ if(gent_pos==0\n    ch=gent&#91;gent_pos];\n    gent_pos=(gent_pos+1)%sizeof(gent);\n  }\n  return(ch);\n}\n\nint ressu_genbyte_limit(int limit)\n{\n  int c;\n  while((c=ressu_genbyte()) >= (256\/limit)*limit);\n  return(c%limit);\n}\n\nint ressu_genshort()\n{\n  return(ressu_genbyte() | ressu_genbyte()&lt;&lt;8);\n}\n\nint ressu_genshort_limit(int limit)\n{\n  int c;\n  while((c=ressu_genshort()) >= (65536\/limit)*limit);\n  return(c%limit);\n}\n\nunsigned int ressu_genint()\n{\n  return(ressu_genshort() | ressu_genshort()&lt;&lt;16);\n}\n\nunsigned int ressu_genint_limit(unsigned long limit)\n{\n  unsigned int c;\n  while((c=ressu_genint()) >= (((unsigned long)65536*65536)\/limit)*limit);\n  return(c%limit);\n}\n\nunsigned long ressu_genlong()\n{\n  return(((unsigned long)ressu_genint()) | ((unsigned long)ressu_genint())&lt;&lt;32);\n}\n\nunsigned long ressu_genlong_limit(unsigned long limit)\n{\n  unsigned long c;\n  while((c=ressu_genlong()) >= (((unsigned long)0xffffffffffffffff)\/limit)*limit);\n  return(c%limit);\n}\n\nunsigned long ressu_gen_limit(unsigned long limit)\n{\n  if(limit&lt;=256)\n    return(ressu_genbyte_limit(limit));\n  else if(limit&lt;=65536)\n    return(ressu_genshort_limit(limit));\n  else if(limit&lt;=(unsigned long)65536*65536)\n    return(ressu_genint_limit(limit));\n  else if(limit&lt;=(unsigned long)0xffffffffffffffff)\n    return(ressu_genlong_limit(limit));\n  else\n    return(-1);\n}\n\n#define MAIN 2\n\n#ifdef MAIN\n\nint help=0;\n\nint utf8len(unsigned char *buf)\n{\n  int len;\n  unsigned char *p;\n  \n  p=buf;\n  len=0;\n  while(*p!='\\0') {\n    if(*p&lt;0x80 || \/\/ ascii char\n       *p>0xbf) \/\/ first utf8 byte\n      len++;\n    p++;\n  }\n  return(len);\n}\n\n#define aDEBUG38 2\n\nvoid utf8getchar(int size, unsigned char *buf, int n, unsigned char *string)\n{\n  int d;\n  unsigned char *p,*q;\n  \n  d=0;\n  p=string;\n  q=buf;\n\n  \/\/ find first byte of character\n  \n  while(*p!='\\0') {\n    if(*p&lt;0x80 || \/\/ ascii char\n       *p>0xbf) { \/\/ first utf8 char\n      if(d==n)\n\tbreak;\n      d++;\n    }\n    p++;\n  }\n\n  \/\/ copy first byte and rest\n  \/\/ of character\n  \n  if(*p!='\\0') {\n    *q++=*p; \/\/ copy first byte\n    if(*p>0xbf) { \/\/ if first is utf8 char\n      p++;\n      for(;;) {\n\tif(*p>0xbf || \/\/ first utf8 char\n\t   *p&lt;0x80 || \/\/ ascii char\n\t   *p=='\\0')  \/\/ end of file\n\t  break;\n\t*q++=*p++; \/\/ copy rest of the bytes\n      }\n    }\n  }\n  *q='\\0';\n\n#ifdef DEBUG38\n  fprintf(stdout,\"%s: utf8getchar:\",procname);\n  fprintf(stdout,\" string: %s\",string);\n  fprintf(stdout,\", n: %d\",n);\n  fprintf(stdout,\", character: %s\",buf);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#define aDEBUG45\n\nvoid out_word(int size, unsigned char *buf, unsigned char *digits, unsigned long word2) \/\/ 8.5.2021 JariK\n{\n  int c, d, len, digitslen;\n  unsigned long word;\n  unsigned char string&#91;132], character&#91;32];\n\n  digitslen = utf8len(digits);\n  word=word2;\n  len=0;\n  string&#91;0]='\\0';\n\n  if(word==0 || digitslen&lt;2) {\n    \/\/ zero\n    utf8getchar(sizeof(character),character,0,digits);\n    if(len+strlen(character)&lt;sizeof(string)) {\n      strcat(string,character);\n      len+=strlen(character);\n    }\n  } else {\n    \/\/ non zero\n    while(word>0) {\n      utf8getchar(sizeof(character),character,word%digitslen,digits);\n      if(len+strlen(character)&lt;sizeof(string)) {\n\tstrcat(string,character);\n\tlen+=strlen(character);\n      }\n      word\/=digitslen;\n    }\n  }\n\n  \/\/ reverse string\n  \n  *buf='\\0';\n  len=0;\n  d=utf8len(string);\n  for(c=d-1;c>=0;c--) {\n    utf8getchar(sizeof(character),character,c,string);\n    if(len+strlen(character)&lt;size) {\n      strcat(buf,character);\n      len+=strlen(character);\n    }\n  }\n\n#ifdef DEBUG45\n  fprintf(stdout,\"]\\n%s: out_word: \",procname);\n  fprintf(stdout,\" reverse string: %s\",string);\n  fprintf(stdout,\", digits: %s\",digits);\n  fprintf(stdout,\", int: %lu\",word2);\n  fprintf(stdout,\"\\n&#91;\");\n#endif\n}\n\n#define aDEBUG58 2\n\nvoid in_word(unsigned long *word, unsigned char *digits, unsigned char *buf)\n{\n  int c,d,e,f,ok;\n  unsigned char character&#91;32], character2&#91;32];\n\n  *word=0;\n  d=utf8len(buf);\n  f=utf8len(digits);\n\n  for(c=0;c&lt;d;c++) {\n    utf8getchar(sizeof(character2),character2,c,buf);\n    ok=0;\n    for(e=0;e&lt;f;e++) {\n      utf8getchar(sizeof(character),character,e,digits);\n      if(!strcmp(character,character2)) {\n\tok=1;\n\tbreak;\n      }\n    }\n    if(ok) {\n      *word=((*word)*f)+e;\n    } else {\n      fprintf(stdout,\"%s: in_word:\",procname);\n      fprintf(stdout,\" illegal digit '%s'\\n\",character2);\n      help=1;\n    }\n  }\n#ifdef DEBUG58\n  fprintf(stdout,\"%s: in_word:\",procname);\n  fprintf(stdout,\" word: %lu\",*word);\n  fprintf(stdout,\", digits: %s\",digits);\n  fprintf(stdout,\", string: %s\",buf);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nvoid line_clear(int *len, unsigned char **buf)\n{\n  if(*len&lt;1) {\n    *len=129;\n    *buf=realloc(*buf,*len);\n  }\n  **buf='\\0';\n}\n\nint line_add_string_sort(int *len, unsigned char **buf, unsigned char *string)\n{\n  int cmp,count,add;\n  unsigned char *p;\n\n  p=*buf;\n  add=1;\n  while(*p!='\\0') {\n    cmp=strncmp(string,p,strlen(string));\n    if(cmp>0) {\n      while(*p!=' ' &amp;&amp; *p!='\\0') \/\/ find next space\n\tp++;\n      while(*p==' ' &amp;&amp; *p!='\\0') \/\/ find next non space\n\tp++;\n    } else if(cmp==0) {\n      add=0;\n      break;\n    } else {\n      break;\n    }\n  }\n\n  if(add) {\n    count=strlen(*buf)+strlen(string)+1+1;\n    if(*buf==NULL || count>*len) {\n      int diff=p-*buf;\n      *len = *len + 128;\n      *buf=realloc(*buf,*len);\n      p=*buf+diff;\n    }\n    memmove(p+strlen(string)+1,p,strlen(p)+1);\n    memmove(p,string,strlen(string));\n    p+=strlen(string);\n    *p=' ';\n  }\n\n  return(add);\n}\n\nvoid line_get_string(int len, unsigned char *buf, int n, unsigned char *string)\n{\n  int e,ok,count;\n  unsigned char *p,*q;\n\n  ok=0;\n  p=string;\n  e=0;\n\n  while(*p!='\\0') {\n    if(e==n) {\n      ok=1;\n      break;\n    }\n    while(*p!=' ' &amp;&amp; *p!='\\0') \/\/ find next space\n      p++;\n    while(*p==' ' &amp;&amp; *p!='\\0') \/\/ find next non space\n      p++;\n    e++;\n  }\n  if(ok) {\n    q=buf;\n    count=0;\n    while(*q!=' ' &amp;&amp; *q!='\\0') {\n      if(++count&lt;len)\n\t*q++=*p;\n      p++;\n    }\n    *q='\\0';\n  } else {\n    buf&#91;0]='\\0';\n  }\n}\n\nvoid line_dump(unsigned char *string)\n{\n  int e,n;\n  unsigned char *p;\n\n  p=string;\n  n=0;\n  while(*p!='\\0') {\n    fprintf(stdout,\" %d:\",n++);\n    while(*p!=' ' &amp;&amp; *p!='\\0') \/\/ find next space\n      putchar(*p++);\n    while(*p==' ' &amp;&amp; *p!='\\0') \/\/ find next non space\n      p++;\n    e++;\n  }\n  fprintf(stdout,\"\\n\");\n}\n\nstatic int size=5, zero=1, sspace=0, scrlf=1,\n  chars=72, pchars=0, words=0, pwords=0,\n  lines=10, plines=0, plinesdigits=5, slineno=1,\n  quiet=0, sort=0, unique=0, sample=0;\nstatic unsigned long limit, word;\nstatic unsigned char *digits=\"0123456789\", character&#91;32];\nstatic unsigned char digitstemp&#91;256];\nstatic unsigned char linenobuf&#91;1024];\n\nunsigned char wordbuf&#91;1024];\n\nvoid readword(unsigned char *buf)\n{\n  int d,e;\n  unsigned char temp1024&#91;1024];\n  \n  if(limit!=0) {\n    word=0;\n    \n    if(zero) {\n      word=ressu_gen_limit(limit); \/\/ include zeroes\n      \/\/fprintf(stdout,\"(%02ld)\",word);\n    } else if(limit>=1) {\n      while((word=ressu_gen_limit(limit))==0); \/\/ skip zeroes\n    }\n\t  \n    out_word(sizeof(temp1024),temp1024,digits,word);\n\t  \n    \/\/ fill leading zeroes\n    \n    buf&#91;0]='\\0';\n    utf8getchar(sizeof(character),character,0,digits);\n    for(d=size-utf8len(temp1024);d>0;d--) {\n      strcat(buf,character);\n    }\n\t  \n    \/\/ rest of the number\n\t  \n    strcat(buf,temp1024);\n\t  \n  } else if(digits!=NULL) {\n    int digitslen;\n\t  \n    buf&#91;0]='\\0';\n    digitslen=utf8len(digits);\n\t  \n    \/\/ fill whole word digit by digit\n\t  \n    \/\/fprintf(stdout,\"&#91;\");\n    for(d=0;d&lt;size;d++) {\n      if(digits&#91;0]=='0' &amp;&amp; !zero)\n\te=ressu_gen_limit(digitslen-1)+1;\n      else\n\te=ressu_gen_limit(digitslen);\n      utf8getchar(sizeof(temp1024),temp1024,e,digits);\n      \/\/fprintf(stdout,\"%s\",temp1024);\n      strcat(buf,temp1024);\n    }\n    \/\/fprintf(stdout,\"]\");\n  }\n}\n\nint line_number_length()\n{\n  int c;\n  out_word(sizeof(linenobuf),linenobuf,\"0123456789\",lines-1);\n  c=strlen(linenobuf);\n  if(c&lt;5)\n    c=5;\n  return(c);\n}\n\nvoid print_line_number()\n{\n  unsigned char linenobuf&#91;1024];\n  \n  if(pchars==0 &amp;&amp; !quiet &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*d\",plinesdigits,plines);\n    fprintf(stdout,\"%s\",linenobuf);\n    pchars +=strlen(linenobuf);\n    fprintf(stdout,\" \");\n    pchars++;\n  }\n}\n\nvoid print_spaces()\n{\n  if(sspace &amp;&amp; pchars>0 &amp;&amp; !quiet) {\n    if(sspace==3 &amp;&amp; pwords%2==0) {\n      fprintf(stdout,\" \");\n      pchars++;\n    }\n    fprintf(stdout,\" \");\n    pchars++;\n  }\n}\n\nvoid print_word(unsigned char *buf)\n{\n  if(size!=0) {\n    if(!quiet)\n      fprintf(stdout,\"%*s\",size,buf);\n    pchars += size;\n    pwords++;\n  } else {\n    if(!quiet)\n      fprintf(stdout,\"%s\",buf);\n    pchars += strlen(wordbuf);\n    pwords++;\n  }\n}\n\n#define aDEBUG86 2\n#define aDEBUG87 2\n#define aDEBUG88 2\n#define aDEBUG89 2\n\nint main(int argc, char *argv&#91;])\n{\n  int c,d;\n \n  procname=argv&#91;0];\n\n  limit=0;\n#ifdef DEBUG4\n  ccp=cc;\n  cc_bytes=0;\n#endif\n  clockbytes=0;\n  for(d=0;d&lt;1024;d++)\n    periods&#91;d]=0;\n\n  \/\/ look thru command line parameters\n  \n  for(c=1;c&lt;argc;c++) {\n    if(!strncmp(\"-\",argv&#91;c],1)) {\n      if(!strcmp(\"--lineno\",argv&#91;c])) {\n\tslineno=!slineno;\n\n      } else if(!strcmp(\"--crlf\",argv&#91;c])) {\n\tscrlf=!scrlf;\n\tslineno=0;\n\n      } else if(!strcmp(\"--quiet\",argv&#91;c])) {\n\tquiet=!quiet;\n\n      } else if(!strcmp(\"--stats\",argv&#91;c]) ||\n\t!strcmp(\"--stat\",argv&#91;c])) {\n\tstats=!stats;\n\n      } else if(!strcmp(\"--space\",argv&#91;c])) {\n\tsspace=!sspace;\n\n      } else if(!strcmp(\"--zero\",argv&#91;c])) {\n\tzero=!zero;\n\n      } else if(!strcmp(\"--sort\",argv&#91;c])) {\n\tsort=!sort;\n\tif(sspace==0)\n\t  sspace=1;\n\t\t\n      } else if(!strcmp(\"--unique\",argv&#91;c])) {\n\tunique=!unique;\n\tif(sspace==0)\n\t  sspace=1;\n\t\t\n      } else if(!strcmp(\"--lotto\",argv&#91;c])) {\n\tsort=!sort;\n\tif(sspace==0)\n\t  sspace=1;\n\t\/\/sort=1;\n\t\/\/unique=1;\n\n      } else if(!strcmp(\"--sample\",argv&#91;c])) {\n\tsample=!sample;\n\t\n      } else if(!strcmp(\"--copyright\",argv&#91;c]) ||\n\t !strcmp(\"--version\",argv&#91;c])) {\n\tfprintf(stderr,\"%s\",programname);\n\tfprintf(stderr,\", %s\",copyright);\n\tfprintf(stderr,\"\\n\\n\");\n\thelp=1;\n\t\n      } else if(!strncmp(\"--lim\",argv&#91;c],5)) {\n\tif(*(argv&#91;c]+5)!='\\0') {\n\t  in_word(&amp;limit, digits, argv&#91;c]+5);\n\t} else if(c+1&lt;argc) {\n\t  in_word(&amp;limit, digits, argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(sspace&lt;1) \/\/ 23.6.2021\n\t  sspace=1;\n\n      } else if(!strncmp(\"-s\",argv&#91;c],2)) {\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  size=atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  size=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tlimit=0; \/\/ 23.6.2021\n\tif(size==0)\n\t  size=1;\n\tif(size>1024)\n\t  size=1024;\n      } else if(!strncmp(\"--bits\",argv&#91;c],6)) {\n\tif(*(argv&#91;c]+6)!='\\0') {\n\t  ressu_bits_needed=atoi(argv&#91;c]+6);\n\t} else if(c+1&lt;argc) {\n\t  ressu_bits_needed=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\t\n\n      } else if(!strncmp(\"--bytes\",argv&#91;c],7)) {\n\tif(*(argv&#91;c]+7)!='\\0') {\n\t  ressut_bytes=atoi(argv&#91;c]+7);\n\t} else if(c+1&lt;argc) {\n\t  ressut_bytes=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\t\n\n      } else if(!strncmp(\"-w\",argv&#91;c],2)) { \/\/ words per line\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  words=atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  words=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(words&lt;1)\n\t  words=1;\n\t\n\tchars = 0;\n\t\n      } else if(!strncmp(\"-c\",argv&#91;c],2)) {  \/\/ characters per line\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  chars=atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  chars=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\twords=0;\n\t\n      } else if(!strncmp(\"-l\",argv&#91;c],2)) { \/\/ lines\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  lines=atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  lines=atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(lines&lt;1)\n\t  lines=1;\n\n      } else if(!strcmp(\"-x\",argv&#91;c])) {\n\tdigits = \"0123456789abcdef\";\n\tsize=4;\n\n      } else if(!strcmp(\"-d\",argv&#91;c])) {\n\tdigits = \"0123456789\";\n\tsize=5;\n\n      } else if(!strcmp(\"-o\",argv&#91;c])) {\n\tdigits = \"01234567\";\n\tsize=3;\n\n      } else if(!strcmp(\"-b\",argv&#91;c])) {\n\tdigits = \"01\";\n\tsize=8;\n\n      } else if(!strcmp(\"-1\",argv&#91;c])) {\n\tdigits=\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tsize=8;\n\n      } else if(!strcmp(\"-2\",argv&#91;c])) {\n\tdigits=\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\" \\\n\t  \"_-\";\n\tsize=8;\n\n      } else if(!strcmp(\"-3\",argv&#91;c])) { \/\/ 9.5.2021 JariK\n\tdigits=\n\t  \"!\\\"#$%&amp;'()*+,-.\/0123456789:;&lt;=>?@\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ&#91;\\\\]^_`\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz{|}~\";\n\tsize=8;\n\n      } else if(!strcmp(\"-4\",argv&#91;c])) {\n\tdigits=\n\t  \"\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\" \\\n\t  \"\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\";\n\tsize=8;\n\n      } else if(!strcmp(\"--isalnum\",argv&#91;c]) || \/\/ 9.5.2021 JariK\n\t        !strcmp(\"--isalpha\",argv&#91;c]) ||\n\t        !strcmp(\"--isdigit\",argv&#91;c]) ||\n\t        !strcmp(\"--isgraph\",argv&#91;c]) ||\n\t        !strcmp(\"--islower\",argv&#91;c]) ||\n\t        !strcmp(\"--isprint\",argv&#91;c]) ||\n\t        !strcmp(\"--ispunct\",argv&#91;c]) ||\n\t        !strcmp(\"--isupper\",argv&#91;c]) ||\n\t\t!strcmp(\"--isxdigit\",argv&#91;c])) {\n\tunsigned char *p=digitstemp;\n\tfor(d=0;d&lt;256;d++) {\n\t  if((!strcmp(\"--isalnum\",argv&#91;c]) &amp;&amp; isalnum(d)) ||\n\t     (!strcmp(\"--isalpha\",argv&#91;c]) &amp;&amp; isalpha(d)) ||\n\t     (!strcmp(\"--isdigit\",argv&#91;c]) &amp;&amp; isdigit(d)) ||\n\t     (!strcmp(\"--isgraph\",argv&#91;c]) &amp;&amp; isgraph(d)) ||\n\t     (!strcmp(\"--islower\",argv&#91;c]) &amp;&amp; islower(d)) ||\n\t     (!strcmp(\"--isprint\",argv&#91;c]) &amp;&amp; isprint(d)) ||\n\t     (!strcmp(\"--ispunct\",argv&#91;c]) &amp;&amp; ispunct(d)) ||\n\t     (!strcmp(\"--isupper\",argv&#91;c]) &amp;&amp; isupper(d)) ||\n\t     (!strcmp(\"--isxdigit\",argv&#91;c]) &amp;&amp; isxdigit(d))) {\n\t    *p++=d;\n\t  }\n\t}\n\t*p='\\0';\n\tdigits=digitstemp;\n\tsize=8;\n\n      } else if(!strcmp(\"--rand\",argv&#91;c])) {\n\tdigits = \"0123456789\";\n\tsspace=3;\n\tslineno=1;\n\twords=10;\n\tchars=0;\n\tlimit=100000;\n\t\/\/size=5;\n\t\/\/lines=20000;\n\t\n      } else if(!strncmp(\"-i\",argv&#91;c],2)) {\n\tdigits=NULL;\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  digits=argv&#91;c]+2;\n\t} else if(c+1 &lt; argc) {\n\t  digits=argv&#91;c+1];\n\t  c++;\n\t}\n\tif(digits==NULL || utf8len(digits)&lt;2) {\n\t  fprintf(stderr,\"%s: not enough digits \\\"%s\\\"\\n\",procname,argv&#91;c]);\n\t  help = 1;\n\t}\n\tsize=1;\n      } else if(!strcmp(\"--ressu\",argv&#91;c])) {\n\tinput=0;\n      } else if(!strcmp(\"--debug\",argv&#91;c])) {\n\tinput=1;\n      } else if(!strcmp(\"--fast\",argv&#91;c])) {\n\tinput=2;\n      } else if(!strcmp(\"--single\",argv&#91;c])) {\n\tinput=3;\n      } else if(!strcmp(\"--urandom\",argv&#91;c])) {\n\tinput=8;\n#ifdef USE_RANDOM\n      } else if(!strcmp(\"--random\",argv&#91;c])) {\n\tinput=9;\n#endif\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\",procname,argv&#91;c]);\n\thelp = 1;\n      }\n    } else {\n      help = 1;\n    } \/\/ if(!strncmp\n  } \/\/ for(c=0\n\n  if(sample) {\n    FILE *fp1;\n    unsigned char buffer&#91;4096];\n\n    fp1=fopen(\"newressusample.rnd\",\"w\");\n    for(c=0;c&lt;1048576;c++) {\n      ressu_genbytes(sizeof(buffer),buffer);\n      fwrite(buffer,1,sizeof(buffer),fp1);\n      ressu_genbytes(sizeof(buffer),buffer);\n      fwrite(buffer,1,sizeof(buffer),fp1);\n    }\n    fclose(fp1);\n    exit(0);\n  }\n  \/\/ get linenumber length in digits\n\n  plinesdigits=line_number_length();\n\n  \/\/ get data length in digits\n\n  if(limit!=0) {\n    unsigned char wordbuf&#91;128];\n    out_word(sizeof(wordbuf),wordbuf,digits,limit-1);\n    size=utf8len(wordbuf);\n  }\n\n  pchars=0;\n  pwords=0;\n  int linew=0;\n\n  \/\/ in beginning of line, count printed line number\n      \n  if(!quiet &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*d\",plinesdigits,plines);\n    pchars += strlen(linenobuf);\n    pchars++;\n  }\n\n  \/\/ count words\n  \n  while((chars>0 &amp;&amp; pchars+size &lt; chars) ||\n\t(words>0 &amp;&amp; pwords &lt; words)) {\n\n    linew++;\n    \n    if(sspace &amp;&amp; pchars>0 &amp;&amp; !quiet) {\n      if(sspace==3 &amp;&amp; pwords%2==0)\n\tpchars++;\n      pchars++;\n    }\n\t\n    pchars+=size;\n    pwords++;\n  }\n\n  unsigned long wordvalues=1;\n  for(c=0;c&lt;size;c++) {\n    if(wordvalues!=0 &amp;&amp; wordvalues*utf8len(digits)&lt;(unsigned long)65536*65536*65536) {\n      wordvalues*=utf8len(digits);\n    } else {\n      wordvalues=0;\n    }\n  }\n\n  if(limit > 0) {\n    if(sort==1 &amp;&amp; limit-!zero&lt;words) {\n      fprintf(stderr,\"%s: limit is less than words (zero)\",procname);\n      fprintf(stderr,\", limit:%lu\",limit);\n      fprintf(stderr,\", words:%d\",words);\n      fprintf(stderr,\", zero:%d\",zero);\n      fprintf(stderr,\"\\n\");\n      \n      help=1;\n      lines=0;\n    }\n  } else {\n    if(sort==1 &amp;&amp; size>0 &amp;&amp; wordvalues>0 &amp;&amp; wordvalues&lt;linew) {\n      fprintf(stderr,\"%s:\",procname);\n      fprintf(stderr,\" digits is less than calculated words\");\n      fprintf(stderr,\", digits:%d(%lu)\",utf8len(digits),wordvalues);\n      fprintf(stderr,\", words:%d\\n\",linew);\n      help=1;\n      lines=0;\n    }\n  }\n\n  \/\/ small words as single ressu_gen_limit()\n  \n  if(limit==0 &amp;&amp; wordvalues>0)\n    limit=wordvalues;\n\n  if(stats) {\n    fprintf(stdout,\"randomsource: %s\",randomgen&#91;input]);\n    fprintf(stdout,\", size: %d\",size);\n    fprintf(stdout,\", linew: %d\",linew);\n    fprintf(stdout,\", pchars: %d\",pchars);\n    fprintf(stdout,\", pwords: %d\",pwords);\n    if(wordvalues>0)\n      fprintf(stdout,\", wordvalues: %lu\",wordvalues);\n    if(limit>0)\n      fprintf(stdout,\", limit: %lu\",limit);\n    fprintf(stdout,\"\\n\");\n  }\n  \n  if(help) {\n    struct helpline {\n      char *command;\n      char *text;\n    } helplines&#91;] = {\n      { \"newressu -d\", \"print random decimal digits\" },\n      { \"newressu -o\", \"print octal digits\" },\n      { \"newressu -x\", \"print hexadecimal digits\" },\n      { \"newressu -b\", \"print binary digits\" },\n      { \"newressu -d --space\", \"print decimal digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -b --space\", \"print binary digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -d -l30\", \"print decimal digits, 30 lines\" },\n      { \"newressu -d -l30 --lineno\", \"print decimal digits, 30 lines, no linenumbers\"  },\n      { \"newressu -d -c128\", \"print decimal digits, 128 characters per line\"  },\n      { \"newressu -d --lim10\", \"print decimal numbers between 0-9\" },\n      { \"newressu -d --lim10 -x\",\"print hexadecimal numbers with decimal limit\" },\n      { \"newressu -d -s10 --space\",\"print decimal numbers with spaces and wordsize 10\" },\n      { \"newressu -d --space --zero --lim7\",\"print rollings of dice (1-6)\" },\n      { \"newressu -b -s1 --space\",\"print throws of coin (0,1)\" },\n      { \"newressu -d --lim41 -w7 --zero --lotto\",\"print lotto numbers for finnish lotto 7x(1-40)\" },\n      { \"newressu -d -s5 --sort -w16\",\"print 16 sorted decimal numbers from 0 to 99999\" },\n      { \"newressu --isalnum\", \"print alphanumeric characters\" },\n      { \"newressu --isalpha\", \"print alphabetic characters\" },\n      { \"newressu --isgraph\", \"print printables excluding space\" },\n      { \"newressu --islower\", \"print lowercase characters\" },\n      { \"newressu --ispunct\", \"print punctuation characters\" },\n      { \"newressu --isupper\", \"print uppercase characters\" },\n      { \"newressu -1\", \"print material for passwords\" },\n      { \"newressu -i\u0430\u044d\u044b\u0443\u043e\u044f\u0435\u0451\u044e\u0438\", \"print russian vowels\" },\n      { \"newressu --ressu\", \"use randomness from ressu (default)\" },\n      { \"newressu --debug\", \"use randomness from debugging ressu\" },\n      { \"newressu --fast\", \"use randomness from fast ressu\" },\n      { \"newressu --single\", \"use randomness from single round of ressu\" },\n      { \"newressu --urandom\", \"use randomness from \/dev\/urandom\" },\n#ifdef USE_RANDOM\n      { \"newressu --random\", \"use randomness from \/dev\/random\" },\n#endif\n    };\n    \n    for(c=0;c&lt;sizeof(helplines)\/sizeof(helplines&#91;0]);c++) {\n      fprintf(stderr,\"%-50s\",helplines&#91;c].text);\n      fprintf(stderr,\"%-25s\",helplines&#91;c].command);\n      fprintf(stderr,\"\\n\");\n    }\n    for(c=0;c&lt;chars;c++)\n      fprintf(stdout,\"*\");\n    fprintf(stdout,\"\\n\");\n    if(lines>1)\n      lines=1; \/\/ print one line below help as a sample\n  }\n\n  if(lines==0)\n    exit(1);\n\n  int linecnt=0;\n  unsigned char *line=NULL;\n  unsigned char wordbuf&#91;1025];\n  \n  for(;;) {\n\n    if(!sort) { \/\/ also lotto\n\n      pchars=0;\n      pwords=0;\n\n      while(pwords&lt;linew) {\n\treadword(wordbuf);\n\n\t\/\/ in beginning of line, print line number\n\n\tprint_line_number();\n\t\n\t\/\/ want to print spaces between \"words\"?\n\n\tprint_spaces();\n\t\n\t\/\/ print word\n\n\tprint_word(wordbuf);\n\n      } \/\/ while(pwords&lt;linew) {\n    } else { \/\/ if(!sort)\n\n      pchars=0;\n      pwords=0;\n      \n      line_clear(&amp;linecnt,&amp;line);\n\n      \/\/ fetch and save words on this row\n      while(pwords&lt;linew) {\n\treadword(wordbuf);\n\n\tif(line_add_string_sort(&amp;linecnt,&amp;line,wordbuf)) {\n\t  pwords++;\n\t}\n      } \/\/ while(pwords&lt;linew) {\n\n      pchars=0;\n      pwords=0;\n\n      \/\/ print words on this row\n      while(pwords&lt;linew) {\n\n\tline_get_string(sizeof(wordbuf),wordbuf,pwords,line);\n\n\t\/\/ in beginning of line, print line number\n\n\tprint_line_number();\n\t\n\t\/\/ want to print spaces between \"words\"?\n\t\n\tprint_spaces();\n\n\t\/\/ print word\n\t\n\tprint_word(wordbuf);\n\n      } \/\/ while(pwords&lt;linew) {\n    } \/\/ if(!sort)\n\n    \/\/ line full?\n    \n    if(!quiet) {\n      fprintf(stdout,\"\\n\");\n    }\n    plines++;\n    if(sspace==3 &amp;&amp; plines&lt;lines &amp;&amp; plines%5==0)\n      fprintf(stdout,\"\\n\");\n\n    \/\/ all needed lines printed?\n\n    if(plines >= lines)\n      break;\n\n  } \/\/ for(;;)\n  fflush(stdout);\n}\n\n#endif \/\/ MAIN<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aiemmasta versiosta on korjattu pari bugia. Ensimm\u00e4isess\u00e4 variaatioissa on vain pieni\u00e4 ketjuja, ja 1,6 rajaa pienten ja suurien ketjujen v\u00e4lill\u00e4 ei l\u00f6ydy. T\u00e4ll\u00f6in lim1 ja lim2 kent\u00e4t t\u00e4ytettiin joskus -1:ll\u00e4. Tietue ensimm\u00e4isest\u00e4 bugista: Toisessa bugissa on eripituisia variaatioita aina 1 kappaletta: jolloin isojen ketjujen ensimm\u00e4inen p\u00e4\u00e4tyy teoreettisiin bitteihin ja _genbytes rutiinista palataan liian nopeasti. T\u00e4ss\u00e4&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=1703\">Continue reading <span class=\"screen-reader-text\">Ressu 2.2 pari korjausta, &#8211;sample optio ja p\u00e4\u00e4ohjelman palastelua<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1703"}],"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=1703"}],"version-history":[{"count":17,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1703\/revisions"}],"predecessor-version":[{"id":1722,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1703\/revisions\/1722"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1703"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1703"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1703"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}