{"id":893,"date":"2020-06-30T22:52:37","date_gmt":"2020-06-30T20:52:37","guid":{"rendered":"https:\/\/moijari.com\/?p=893"},"modified":"2020-07-08T23:05:28","modified_gmt":"2020-07-08T21:05:28","slug":"debuggaillaan-ressun-kelloketjuja","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=893","title":{"rendered":"Debuggaillaan ressun kelloketjuja"},"content":{"rendered":"\n<p>T\u00e4ss\u00e4 uusi debukkailuversio ressun kellon luvusta. T\u00e4m\u00e4 lukee kelloa puskurillisen kerrallaan, tavallisen kellomerkki kerrallaan tavan sijasta. J\u00e4lkimm\u00e4inen tapa ei ole kovin mukava debukkailijan kannalta, koska kellojono tietysti etenee debukkaustulosteiden tulostamisen aikana ja kellojonot lyhenev\u00e4t, joskus h\u00e4vi\u00e4v\u00e4t kokonaan. Kellomerkkej\u00e4 voi olla vain yksi per kellon arvo.<\/p>\n\n\n\n<p>Edit: Tehty korjauksia julkaisun j\u00e4lkeisten viikkojen aikana. Lis\u00e4ksi muotoilin ohjelman uudelleen siten ett\u00e4 my\u00f6s puuttuvat ketjut lis\u00e4\u00e4v\u00e4t tarvittaessa yhden bitin teoreettista satunnaisuutta. Muutokset ovat kappaleessa if(prevbyte != byte).<\/p>\n\n\n\n<p>T\u00e4ss\u00e4 postissa on my\u00f6s kellojonojen debukkailuun tarkoitettu versio ressu_genbytes() rutiinista. Se tulostaa teoreettisten satunnaisbittien laskentaan liittyvi\u00e4 tietoja.<\/p>\n\n\n\n<p>Mutta ensin uusi versio kellon luennasta. Ohjelma lukee kellojonon merkit clock_bytes[] taulukkoon ja palauttaa merkkej\u00e4 yhden kerrallaan. Uudessa luennassa yritet\u00e4\u00e4n uusi puskuri aloittaa edellisen puskurin viimeisell\u00e4 arvolla (cb), jos t\u00e4m\u00e4 ei ole ensimm\u00e4inen puskuri (clock_byte!=99&#8230;). Clock_bytes[], clock_byte, clock_cnt ja niiden k\u00e4ytt\u00f6 ovat tuttuja jo ressu_genbyte() rutiinista, toki ressu_ alkuisina kenttin\u00e4. Kun haluat lopettaa kellon debukkaamisen, lis\u00e4\u00e4 kommentti #define DEBUG_CLOCK lauseeseen tai lis\u00e4\u00e4 pikku-a sen DEBUG_CLOCK sanan ensimm\u00e4iseksi kirjaimeksi.<\/p>\n\n\n\n<p>Kellojonot toki pitenev\u00e4t t\u00e4ss\u00e4 versiossa, koska ne talletetaan t\u00e4ss\u00e4 nopeassa luupissa (for(int c=0&#8230;). Toisaalta luulisin ett\u00e4 ilman debukkia kellojonojen pituuksissa on enemm\u00e4n vaihtelua.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG_CLOCK 2\n\n#ifdef DEBUG_CLOCK\n#define CLOCKCNT 256\n\nunsigned char clock_bytes&#91;CLOCKCNT];\nint clock_byte = 999999999;\nint clock_cnt = CLOCKCNT;\n\nunsigned char clockbyte() \/* JariK 2020 *\/\n{\n  if(clock_byte >= clock_cnt) {\n    struct timeval tv;\n    if(clock_byte != 999999999) {\n      unsigned char cb;\n      gettimeofday(&amp;tv, NULL);\n      cb = tv.tv_usec &amp; 0xff;\n      while(cb != clock_bytes&#91;clock_cnt-1]) {\n        gettimeofday(&amp;tv, NULL);\n        cb = tv.tv_usec &amp; 0xff;\n      }\n    }\n    for(int c = 0; c &lt; CLOCKCNT; c++) {\n      gettimeofday(&amp;tv, NULL);\n      clock_bytes&#91;c] = tv.tv_usec &amp; 0xff;\n    }\n    clock_byte = 0;\n  }\n  return(clock_bytes&#91;clock_byte++]);\n}\n\n#else \/\/#ifdef DEBUG_CLOCK                                                                                                                                                                                  \n\nunsigned char clockbyte() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return(tv.tv_usec &amp; 0xff);\n}\n\n#endif \/\/#ifdef DEBUG_CLOCK<\/code><\/pre>\n\n\n\n<p>Sitten kellojonojen debukkailuun tarkoitettu versio ressu_genbytes() rutiinista: Raportin tulostaa kappale, joka alkaa tulostustiedoston avaamisella (fp1=fopen).<\/p>\n\n\n\n<p>Toinen ero oikeaan versio 1.8 rutiiniin on tuo rndbits kent\u00e4n kasvatus kahdella, eli yksi poikkeusjono on kaksi bitti\u00e4 satunnaisuutta. Ajatus on ett\u00e4 poikkeus olisi &#8220;ykk\u00f6sbitti&#8221; ja sille voidaan laskea ylim\u00e4\u00e4r\u00e4inen &#8220;nollabitti&#8221; noista perusjonoista, joita yritet\u00e4\u00e4n olla laskematta. T\u00e4m\u00e4 teoriassa lyhent\u00e4\u00e4 suoritusaikaa. Hmmmmm&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes(int size, unsigned char *buffer) \/* JariK 2020 v1.8 *\/\n{\n  int c, d, e, f, g,\n    byte, prevbyte,\n    clockbytes = 0, rndbits = 0,\n    chainbytes = 0, oldindex = 0, oldcount;\n  unsigned char olddata&#91;10];\n\n  memset(olddata, 0, sizeof(olddata));\n  prevbyte = clockbyte();\n  f = 0;\n\n  for(c = 0; c &lt; 8 || c%8 != 0 || \n      clockbytes &lt; 2000 ||\n      rndbits &lt; 8*size; c++) {\n\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);\n      byte = clockbyte();\n      buffer&#91;d] = e^byte;\n\n      if(prevbyte != byte) {\n        oldcount = 0;\n        for(g = 0; g &lt; sizeof(olddata); g++) {\n          if(olddata&#91;g] == chainbytes)\n            oldcount++;\n        }\n\n        int tbit, tbit2;\n        tbit=0;\n        tbit2=0;\n        if(oldcount &lt; 4) {\n          tbit=1;\n          rndbits+=2;                                                                                                                            \n        } else if((prevbyte+1)%256 != byte) {\n          tbit2=1;\n          rndbits++;\n        }\n\n        FILE *fp1;\n        if((fp1 = fopen(\"ressuchains.deb\",\n            \"a\")) != NULL) {\n          fprintf(fp1,\"id=%d\", id);\n          fprintf(fp1,\", c=%3d\", c);\n          fprintf(fp1,\", c%%8=%d\", c%8);\n          fprintf(fp1,\", prevbyte=%3d\",\n              prevbyte);\n          fprintf(fp1,\", byte=%3d\",\n              byte);\n          fprintf(fp1,\", tbits=%4d\",\n              rndbits);\n          fprintf(fp1,\", length=%2d\",\n              chainbytes);\n          fprintf(fp1,\", tbit=%d\", tbit);\n          fprintf(fp1,\", tbit2=%d\", tbit2);\n          fprintf(fp1,\", oldcount=%d\",\n              oldcount);\n          fprintf(fp1,\", data=\");\n          for(g = 0; g &lt; sizeof(olddata); g++)\n            fprintf(fp1,\" %02d\",\n                olddata&#91;g]);\n          fprintf(fp1,\"\\n\");\n          fclose(fp1);\n          id++;\n        } \/\/ if((fp1\n\n        olddata&#91;oldindex] = chainbytes;\n        oldindex = (oldindex + 1) %\n            sizeof(olddata);\n\n        clockbytes += chainbytes;\n        chainbytes = 0;\n\n        prevbyte = byte;\n      } \/\/ if(prevbyte != byte)\n      chainbytes++;\n    } \/\/ for(d = 0;\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    } \/\/ for(d = 0\n  } \/\/ for(c = 0\n}\n<\/code><\/pre>\n\n\n\n<p>Edellisen rutiinin tuloste: T\u00e4m\u00e4 on ehk\u00e4 v\u00e4h\u00e4n lukukelvoton t\u00e4ll\u00e4 kapealla palstalla, mutta t\u00e4ss\u00e4 n\u00e4kyy kuitenkin t\u00e4rkeimm\u00e4t numerot, c:ss\u00e4 on p\u00e4\u00e4luupin (for(c=0) kierroksen numero, c%8 kertoo k\u00e4sitelt\u00e4v\u00e4n bitin numeron v\u00e4lill\u00e4 0-7, byte kertoo kellomerkin arvon, tbits kertoo teoreettisten bittien lukum\u00e4\u00e4r\u00e4n, length taas t\u00e4m\u00e4n kellojonon pituuden, tbit kertoo onko t\u00e4ll\u00e4 rivill\u00e4 ollut teoreettinen satunnaisbitti vai ei, oldcount antaa t\u00e4m\u00e4n pituuden esiintymien lukum\u00e4\u00e4r\u00e4n. Data kent\u00e4ss\u00e4 on kaikkien kymmenen viimeisen kellojonon pituudet. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>id=568, c= 52, c%8=4, byte=127, tbits= 552, length=23, tbit=1, oldcount=1, data= 49 26 24 26 24 26 22 26 23 51\nid=569, c= 53, c%8=5, byte=128, tbits= 552, length=26, tbit=0, oldcount=5, data= 49 26 24 26 24 26 22 26 23 26\nid=570, c= 53, c%8=5, byte=129, tbits= 554, length=27, tbit=1, oldcount=1, data= 27 26 24 26 24 26 22 26 23 26\nid=571, c= 53, c%8=5, byte=130, tbits= 556, length=25, tbit=1, oldcount=1, data= 27 25 24 26 24 26 22 26 23 26\nid=572, c= 53, c%8=5, byte=131, tbits= 558, length=23, tbit=1, oldcount=2, data= 27 25 23 26 24 26 22 26 23 26\nid=573, c= 53, c%8=5, byte=132, tbits= 560, length=27, tbit=1, oldcount=2, data= 27 25 23 27 24 26 22 26 23 26\nid=574, c= 54, c%8=6, byte=133, tbits= 560, length=26, tbit=0, oldcount=4, data= 27 25 23 27 26 26 22 26 23 26\nid=575, c= 54, c%8=6, byte=134, tbits= 562, length=25, tbit=1, oldcount=2, data= 27 25 23 27 26 25 22 26 23 26<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 yksi sivuhuomautus: t\u00e4ss\u00e4 ovat esiintyneet kaikki byte arvot eli kellon arvot v\u00e4lill\u00e4 127-134, mik\u00e4 lienee yleisin tapaus. Voisi kuvitella ett\u00e4 on tilanteita jossa ohitetaan yksi kelloarvo kokonaan, esimerkiksi hidas kone tms. Se voisi olla teoreettisen satunnaisbitin paikka, ainakin siin\u00e4 tapauksessa ettei bittej\u00e4 muuten saada laskettua. Jos esimerkiksi kaikki kellojonot on yhden merkin pituisia, meill\u00e4 on data taulukko t\u00e4ynn\u00e4 ykk\u00f6si\u00e4 (10 kpl), j\u00e4lleen uutta ykk\u00f6st\u00e4 ei tietenk\u00e4\u00e4n lasketa. Jos t\u00e4ss\u00e4 tilanteessa olisi kellon arvoilla v\u00e4lej\u00e4 saataisiin silti kasvatettua satunnaisbittej\u00e4. Teoreettinen huomautus, toivottavasti. <\/p>\n\n\n\n<p>Sitten pieni p\u00e4\u00e4ohjelma<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void main(int argc,char *argv&#91;])\n{\n  int c;\n  unsigned char buffer&#91;128];\n\n  FILE *fp1;\n  if((fp1 = fopen(\"ressuchains.deb\",\n      \"w\")) != NULL)\n    fclose(fp1);\n\n  for(c = 0; c &lt; 20; c++)\n    ressu_genbytes(sizeof(buffer), buffer);\n\n  for(c = 0; c &lt; sizeof(buffer); c++) {\n    if(c > 0 &amp;&amp; c%32 == 0)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\" %02x\", buffer&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e4ss\u00e4 uusi debukkailuversio ressun kellon luvusta. T\u00e4m\u00e4 lukee kelloa puskurillisen kerrallaan, tavallisen kellomerkki kerrallaan tavan sijasta. J\u00e4lkimm\u00e4inen tapa ei ole kovin mukava debukkailijan kannalta, koska kellojono tietysti etenee debukkaustulosteiden tulostamisen aikana ja kellojonot lyhenev\u00e4t, joskus h\u00e4vi\u00e4v\u00e4t kokonaan. Kellomerkkej\u00e4 voi olla vain yksi per kellon arvo. Edit: Tehty korjauksia julkaisun j\u00e4lkeisten viikkojen aikana. Lis\u00e4ksi muotoilin ohjelman&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=893\">Continue reading <span class=\"screen-reader-text\">Debuggaillaan ressun kelloketjuja<\/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,11],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/893"}],"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=893"}],"version-history":[{"count":38,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/893\/revisions"}],"predecessor-version":[{"id":936,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/893\/revisions\/936"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}