{"id":1874,"date":"2022-11-16T17:31:56","date_gmt":"2022-11-16T15:31:56","guid":{"rendered":"https:\/\/moijari.com\/?p=1874"},"modified":"2025-06-27T14:46:40","modified_gmt":"2025-06-27T12:46:40","slug":"newressu-version-bumped-to-3-0","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=1874","title":{"rendered":"Newressu(4.10): in search for randomness. reduced sha256 calls in stream cipher (stream_bytes), rewrote pseudoressu_bytes(), sudokues everywhere, new look at database db8, query utility to debug db8, added switch (&#8211;query) to newressusudoku to use db8 query, added more function to db8 query, added sudokuid to sudoku record, added semaphores as sudokuid locking"},"content":{"rendered":"\n<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n \u00a9. Maailman parhaat satunnaisbitit: <a href=\"https:\/\/moijari.com:5006\">https:\/\/moijari.com:5006<\/a>. <\/p>\n\n\n\n<p>Suomessa lahjoituksen voi tehd\u00e4, mutta sit\u00e4 ei voi pyyt\u00e4\u00e4. Jos haluat lahjoittaa kuitenkin projektille, laita lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Jos lahjoitat sata euroa tai enemm\u00e4n ja haluat vastalahjan, saat vastalahjana sudokun. Vastalahjasudokua varten kirjoita s\u00e4hk\u00f6postiviesti osoitteeseen moijaricom@gmail.com ja laita viestiin aiemmat pankkitapahtuman viestiss\u00e4 mainitut nimesi ja asuinpaikkakuntasi ja postiosoitteesi sudokun l\u00e4hetyst\u00e4 varten. Laita s\u00e4hk\u00f6postiviestin otsakkeeksi vastalahjasudoku. L\u00e4het\u00e4n yhden sudokun jokaisesta sata euroa ylitt\u00e4v\u00e4st\u00e4 lahjoituksesta. My\u00f6s pienet lahjoitukset (euro tai kaksi) ovat tervetulleita. Kiitokset lahjoituksestasi.<\/p>\n\n\n\n<p>Versionumeron kasvatuksen yhteydess\u00e4 k\u00e4yn l\u00e4pi kaikki uudet ja vanhat p\u00e4\u00e4funktiot.<\/p>\n\n\n\n<p>Edit: korjailen raporttia viel\u00e4 seuraavien viikkojen aikana<\/p>\n\n\n\n<p>Edit: olen jatkanut ressun tutkimista ja lis\u00e4ilen illan mittaan uusia kappaleita raporttiin. Lis\u00e4tty kaksi uutta tilastoohjelmaa, uudelleenkirjoituskappaleet stat_line funktioista ja sample() rutiinista. Toinen tilastoohjelma sis\u00e4lt\u00e4\u00e4 tertun ytimelle toivottavasti sopivan kenttien ja tietueiden hallinnan pohjan.<\/p>\n\n\n\n<p>Edit Lis\u00e4tty loppuun kappaleita exfat bugin korjaamisesta. Bugi korjautui osittain lis\u00e4\u00e4m\u00e4ll\u00e4 tulostettavaan tiedostoon fflush ja sync.<\/p>\n\n\n\n<p>Edit: v\u00e4hennetty stat_line:n &#8220;nykimist\u00e4&#8221;. Numerokent\u00e4t (readable) ovat nyt useimmiten nelj\u00e4n pituisia.<\/p>\n\n\n\n<p>Edit: Lis\u00e4\u00e4 exfat ongelman tutkimista. Lis\u00e4tty ohjelma newressutest12, joka kirjoittaa kiinte\u00e4n pituisia tietueita ja lukee ja tarkistaa tietueet. (vrt newressutest10)<\/p>\n\n\n\n<p>Edit: Muutettu komentoriviparametrej\u00e4 samankaltaisiksi. Ennen parametrit olivat esimerkiksi -b, &#8211;bytes, &#8211;lines, ne olivat erilaisia joka ohjelmassa. Nyt ne on samanlaisia eli &#8211;filesize 1g, &#8211;binsize 10, &#8211;linesize 21, &#8211;lines 1m, &#8211;blocksize 1024, &#8211;blocks 1m jne. Muutenkin n\u00e4iden parametrien laskentaa ja tarkistusta on j\u00e4rkeistetty. Huomaa, ett\u00e4 raportin komentoesimerkeiss\u00e4 vanhat versiot eiv\u00e4t en\u00e4\u00e4 toimi. My\u00f6s ,\/newressu &#8211;sample &#8211;filesize 1g ja muut koko-parametrit toimivat.<\/p>\n\n\n\n<p>Edit: Lis\u00e4tty stream_open -funktion avaimen muodostukseen stream_keyn lis\u00e4ksi cvar. T\u00e4m\u00e4 tekee uudesta stream_key:st\u00e4 satunnaisemman. N\u00e4in samoja stream_key avaimia ei kierret\u00e4 uudelleen ja uudelleen. Jos jostain syyst\u00e4 p\u00e4\u00e4dymme samaan stream_key:in toistamiseen, seuraavan avaimen laskemiseen k\u00e4ytet\u00e4\u00e4n erilaista cvar kentt\u00e4\u00e4, jolloin saman sarjan l\u00e4pik\u00e4yminen loppuu heti.<\/p>\n\n\n\n<p>Edit: lis\u00e4tty newressu ohjelmaan &#8211;columns kytkin, jolla saa sarakenumerot sarakkeiden yl\u00e4puolelle.<\/p>\n\n\n\n<p>Edit V\u00e4hennetty lis\u00e4\u00e4 stat_line:n nykimist\u00e4. Nyt my\u00f6s left ja end kent\u00e4t heiluvat v\u00e4hemm\u00e4n.<\/p>\n\n\n\n<p>Edit: lis\u00e4tty sample() satunnaislukutiedoston muodostukseen grep:ill\u00e4 tulostettava automaattinen ongelmien lista.<\/p>\n\n\n\n<p>Edit: Lis\u00e4tty &#8211;som komento-optio, jolla tulostetaan somalian merkkijonoja. Ensimm\u00e4isess\u00e4 versiossa ei<\/p>\n\n\n\n<p>Edit: Lis\u00e4tty integrity testi, jossa aina (DEBUG72) .\/newressu ajon alussa kirjoitetaan useimmilla &#8211;kytkimill\u00e4 rivej\u00e4 newressutest14.rnd* tiedostoon. Jokaiselle p\u00e4iv\u00e4lle luodaan oma tiedostonsa.<\/p>\n\n\n\n<p>Edit: Viel\u00e4 listaus ressun ytimest\u00e4 ilman copy\/reverse\u00e4 ja tilastollisia laskelmia, jotta nopeasti ymm\u00e4rr\u00e4t mik\u00e4 t\u00e4m\u00e4 ressun syd\u00e4n on. Seuraavassa on yksi kahdeksan bitin kierros ressua. Ydint\u00e4 ajetaan kunnes kaikki tilastolliset satunnaisbittien m\u00e4\u00e4r\u00e4n arvioinnit t\u00e4yttyv\u00e4t:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define RR8(byte, bits) ( ((byte) &gt;&gt; (bits)) | ((byte) &lt;&lt; (8 - (bits))) )\n#define RL8(byte, bits) ( ((byte) &gt;&gt; (8 - (bits))) | ((byte) &lt;&lt; (bits)) )\n\nvoid ressu_genbytes_single_do(int size, unsigned char *buffer) \/\/ JariK 2013\n{\n  int c, d;\n  unsigned char e;\n  static int f = 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 = RL8(e, 1); \/\/ rotate byte left 1 bits\n      \/\/e = RL8(e, 3); \/\/ rotate byte left 3 bits\n      \/\/e = RR8(e, 1); \/\/ rotate byte right 1 bits\n      buffer&#91;d] = e ^ ressu_clockbyte();\n    }\n    for(d = 0; d &lt; size; d++) {\n      f = (f + buffer&#91;d] + 2) % size; \/\/ + 2 JariK 2022\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Asiasta toiseen tuo edellisen koodin + 2 on ns + 2 bugi, joka korjataan t\u00e4ss\u00e4 raportissa. Tuo clockbyte() palauttaa k\u00e4ytett\u00e4v\u00e4n kellojonon, sis\u00e4lt\u00e4\u00e4 copy\/reverse koodin ja perus tilastojen laskennan koodin. Kutsuvassa rutiinissa taas on teoreettisten satunnaisbittien laskennan toiminnot ja vertailut.<\/p>\n\n\n\n<p>Edit: lis\u00e4sin flags rakenteen t\u00e4h\u00e4n alkuun, jotta se l\u00f6ytyisi raportista helpommin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct idflags { \/\/ 202307 JariK\n  unsigned char *id;\n  unsigned char *flags;\n} idsflags&#91;] = {\n  { \"\ud83c\uddeb\ud83c\uddee\", \"\ud83c\uddeb\ud83c\uddee: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND\" },\n  { \"\ud83c\udde6\ud83c\uddfd\", \"\ud83c\udde6\ud83c\uddfd: ax, ala, \u00c5land, aland, NORDIC, FINLAND\" },\n  { \"\ud83c\uddf8\ud83c\uddea\", \"\ud83c\uddf8\ud83c\uddea: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\uddf3\ud83c\uddf4\", \"\ud83c\uddf3\ud83c\uddf4: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\udde9\ud83c\uddf0\", \"\ud83c\udde9\ud83c\uddf0: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK\" },\n  { \"\ud83c\uddeb\ud83c\uddf4\", \"\ud83c\uddeb\ud83c\uddf4: fo, fro, FaroeIslands, NORDIC, DENMARK\" },\n  { \"\ud83c\uddee\ud83c\uddf8\", \"\ud83c\uddee\ud83c\uddf8: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\uddec\ud83c\uddf1\", \"\ud83c\uddec\ud83c\uddf1: gl, grl, Greenland, NORTHAMERICA, NORDIC, DENMARK\" },\n  \n  { \"\ud83c\uddea\ud83c\uddea\", \"\ud83c\uddea\ud83c\uddea: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddfb\", \"\ud83c\uddf1\ud83c\uddfb: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddf9\", \"\ud83c\uddf1\ud83c\uddf9: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  \n  { \"\ud83c\uddfa\ud83c\udde6\", \"\ud83c\uddfa\ud83c\udde6: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf1\", \"\ud83c\udde6\ud83c\uddf1: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\udde9\", \"\ud83c\udde6\ud83c\udde9: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf2\", \"\ud83c\udde6\ud83c\uddf2: am, arm, Armenia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf9\", \"\ud83c\udde6\ud83c\uddf9: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddff\", \"\ud83c\udde6\ud83c\uddff: az, aze, Azerbaijan, EASTERNEUROPE, EUROPE, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddfe\", \"\ud83c\udde7\ud83c\uddfe: by, blr, Belarus, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddea\", \"\ud83c\udde7\ud83c\uddea: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udde6\", \"\ud83c\udde7\ud83c\udde6: ba, bih, BosniaandHerzegovina, EASTERNEUROPE, EUROPE\" }, \/\/ Bosnia and Herzegovina\n  { \"\ud83c\udde7\ud83c\uddec\", \"\ud83c\udde7\ud83c\uddec: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udded\ud83c\uddf7\", \"\ud83c\udded\ud83c\uddf7: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\uddfe\", \"\ud83c\udde8\ud83c\uddfe: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde8\ud83c\uddff\", \"\ud83c\udde8\ud83c\uddff: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA\" },  \/\/ Czech Republic Czechia\n  { \"\ud83c\uddeb\ud83c\uddf7\", \"\ud83c\uddeb\ud83c\uddf7: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddec\ud83c\uddea\", \"\ud83c\uddec\ud83c\uddea: ge, geo, Georgia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde9\ud83c\uddea\", \"\ud83c\udde9\ud83c\uddea: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddec\ud83c\uddf7\", \"\ud83c\uddec\ud83c\uddf7: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udded\ud83c\uddfa\", \"\ud83c\udded\ud83c\uddfa: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf9\", \"\ud83c\uddee\ud83c\uddf9: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddfb\ud83c\udde6\", \"\ud83c\uddfb\ud83c\udde6: va, vat, Vatican, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddff\", \"\ud83c\uddf0\ud83c\uddff: kz, kaz, Kazakhstan, EUROPE, EURASIA, CENTRALASIA, ASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddee\", \"\ud83c\uddf1\ud83c\uddee: li, lie, Liechtenstein, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddfa\", \"\ud83c\uddf1\ud83c\uddfa: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf9\", \"\ud83c\uddf2\ud83c\uddf9: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\udde9\", \"\ud83c\uddf2\ud83c\udde9: md, mda, Moldova, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddea\", \"\ud83c\uddf2\ud83c\uddea: me, mne, Montenegro, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\udde8\", \"\ud83c\uddf2\ud83c\udde8: mc, mco, Monaco, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddea\", \"\ud83c\uddf2\ud83c\uddea: me, mne, Montenegro, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf1\", \"\ud83c\uddf3\ud83c\uddf1: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf0\", \"\ud83c\uddf2\ud83c\uddf0: mk, mkd, Northmacedonia, EASTERNEUROPE, EUROPE, EURASIA\" }, \/\/ North Macedonia\n  { \"\ud83c\uddf5\ud83c\uddf1\", \"\ud83c\uddf5\ud83c\uddf1: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf9\", \"\ud83c\uddf5\ud83c\uddf9: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf7\ud83c\uddf4\", \"\ud83c\uddf7\ud83c\uddf4: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf7\ud83c\uddfa\", \"\ud83c\uddf7\ud83c\uddfa: ru, rus, Russia, EASTERNEUROPE, EUROPE, EURASIA, NORTHASIA, ASIA, BRICS\" },\n  { \"\ud83c\uddf8\ud83c\uddf2\", \"\ud83c\uddf8\ud83c\uddf2: sm, smr, SanMarino, SOUTHERNEUROPE, EUROPE, EURASIA\" }, \/\/ San Marino\n  { \"\ud83c\uddf7\ud83c\uddf8\", \"\ud83c\uddf7\ud83c\uddf8: rs, srb, Serbia, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddf0\", \"\ud83c\uddf8\ud83c\uddf0: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddee\", \"\ud83c\uddf8\ud83c\uddee: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddea\ud83c\uddf8\", \"\ud83c\uddea\ud83c\uddf8: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\udded\", \"\ud83c\udde8\ud83c\udded: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf7\", \"\ud83c\uddf9\ud83c\uddf7: tr, tur, Turkey, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  \n  { \"\ud83c\uddec\ud83c\udde7\", \"\ud83c\uddec\ud83c\udde7: gb, gbr, UnitedKingdom, UK, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, England, UK\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, Scotland, UK\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, Wales, UK\" },\n\n  { \"\ud83c\uddec\ud83c\uddee\", \"\ud83c\uddec\ud83c\uddee: gi, gib, Gibraltar, UK\" },\n\n  { \"\ud83c\uddf8\ud83c\uddef\", \"\ud83c\uddf8\ud83c\uddef: sj, sjm, JanMayen, NORWAY\" }, \/\/ Jan Mayen\n  \n  { \"\ud83c\udde6\ud83c\uddee\", \"\ud83c\udde6\ud83c\uddee: ai, aia, Anguilla, NORTHAMERICA, UK\" },\n  { \"\ud83c\udde6\ud83c\uddec\", \"\ud83c\udde6\ud83c\uddec: ag, atg, AntiguaAndBarbuda, NORTHAMERICA\" }, \/\/ Antigua and Barbuda \n  { \"\ud83c\udde6\ud83c\uddfc\", \"\ud83c\udde6\ud83c\uddfc: aw, sbw, Aruba, NORTHAMERICA\" }, \n  { \"\ud83c\udde7\ud83c\uddf8\", \"\ud83c\udde7\ud83c\uddf8: bs, bhs, Bahamas, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\udde7\", \"\ud83c\udde7\ud83c\udde7: bb, brb, Barbados, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddff\", \"\ud83c\udde7\ud83c\uddff: bz, blz, Belize, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf2\", \"\ud83c\udde7\ud83c\uddf2: bm, bmu, Bermuda, UK, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf6\", \"\ud83c\udde7\ud83c\uddf6: bq, bes, Bonaire, NETHERLANDS, NORTHAMERICA\" },\n  { \"\ud83c\uddfb\ud83c\uddec\", \"\ud83c\uddfb\ud83c\uddec: vg, vgb, BritishVirginIslands, UK, NORTHAMERICA\" }, \/\/ British Virgin Islands\n  { \"\ud83c\udde8\ud83c\udde6\", \"\ud83c\udde8\ud83c\udde6: ca, can, Canada, NORTHAMERICA\" },\n  { \"\ud83c\uddf0\ud83c\uddfe\", \"\ud83c\uddf0\ud83c\uddfe: ky, cym, CaymanIslands, UK, NORTHAMERICA\" },\n  { \"\ud83c\uddeb\ud83c\uddf7\", \"\ud83c\uddeb\ud83c\uddf7: fr, fra, ClippertonIsland, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddf7\", \"\ud83c\udde8\ud83c\uddf7: cr, cri, CostaRica, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddfa\", \"\ud83c\udde8\ud83c\uddfa: cu, cub, Cuba, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddfc\", \"\ud83c\udde8\ud83c\uddfc: cw, cuw, Cura\u00e7ao, curacao, NORTHAMERICA\" },\n  { \"\ud83c\udde9\ud83c\uddf2\", \"\ud83c\udde9\ud83c\uddf2: dm, dma, Dominica, NORTHAMERICA\" },\n  { \"\ud83c\udde9\ud83c\uddf4\", \"\ud83c\udde9\ud83c\uddf4: do, dom, DominicanRepublic, NORTHAMERICA\" }, \/\/ Dominican Republic\n  { \"\ud83c\uddf8\ud83c\uddfb\", \"\ud83c\uddf8\ud83c\uddfb: sv, slv, ElSalvador, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf1\", \"\ud83c\uddec\ud83c\uddf1: gl, grl, Greenland, DENMARK, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\udde9\", \"\ud83c\uddec\ud83c\udde9: gd, grd, Grenada, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf5\", \"\ud83c\uddec\ud83c\uddf5: gp, glp, Guadeloupe, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf9\", \"\ud83c\uddec\ud83c\uddf9: gt, gtm, Guatemala, NORTHAMERICA\" },\n  { \"\ud83c\udded\ud83c\uddf9\", \"\ud83c\udded\ud83c\uddf9: ht, hti, Haiti, NORTHAMERICA\" },\n  { \"\ud83c\udded\ud83c\uddf3\", \"\ud83c\udded\ud83c\uddf3: hn, hnd, Honduras, NORTHAMERICA\" },\n  { \"\ud83c\uddef\ud83c\uddf2\", \"\ud83c\uddef\ud83c\uddf2: jm, jam, Jamaica, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf6\", \"\ud83c\uddf2\ud83c\uddf6: mq, mtq, Martinique, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfd\", \"\ud83c\uddf2\ud83c\uddfd: mx, mex, Mexico, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf8\", \"\ud83c\uddf2\ud83c\uddf8: ms, msr, Montserrat, UK, NORTHAMERICA\" },\n  { \"\ud83c\uddf3\ud83c\uddee\", \"\ud83c\uddf3\ud83c\uddee: ni, nic, Nicaragua, NORTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\udde6\", \"\ud83c\uddf5\ud83c\udde6: pa, pan, Panama, NORTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddf7\", \"\ud83c\uddf5\ud83c\uddf7: pr, pri, PuertoRico, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf6\", \"\ud83c\udde7\ud83c\uddf6: bq, bes, Saba, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf1\", \"\ud83c\udde7\ud83c\uddf1: bl, blm, SaintBarth\u00e9lemy, saintbarthelemy, NORTHAMERICA\" }, \/\/ Saint Barth\u00e9lemy\n  { \"\ud83c\uddf0\ud83c\uddf3\", \"\ud83c\uddf0\ud83c\uddf3: kn, kna, SaintKitts, NORTHAMERICA\" }, \/\/ Saint Kitts and Nevis\n  { \"\ud83c\uddf1\ud83c\udde8\", \"\ud83c\uddf1\ud83c\udde8: lc, lca, SaintLucia, NORTHAMERICA\" }, \/\/ Saint Lucia\n  { \"\ud83c\uddf2\ud83c\uddeb\", \"\ud83c\uddf2\ud83c\uddeb: mf, maf, SaintMartin, NORTHAMERICA\" }, \/\/ Collectivity of Saint Martin\n  { \"\ud83c\uddf8\ud83c\uddfd\", \"\ud83c\uddf8\ud83c\uddfd: sx, sxm, SintMaarten, NORTHAMERICA\" }, \/\/ Sint Maarten\n  { \"\ud83c\uddf9\ud83c\uddf9\", \"\ud83c\uddf9\ud83c\uddf9: tt, tto, TrinidadandTobago, NORTHAMERICA\" }, \/\/ Trinidad and Tobago\n  { \"\ud83c\uddf9\ud83c\udde8\", \"\ud83c\uddf9\ud83c\udde8: tc, tca, TurksandCaicos, UK, NORTHAMERICA\" }, \/\/ Turks and Caicos Islands\n  { \"\ud83c\uddf5\ud83c\uddf2\", \"\ud83c\uddf5\ud83c\uddf2: pm, spm, SaintPierre, NORTHAMERICA\" }, \/\/ Saint Pierre and Miquelon\n  { \"\ud83c\uddfb\ud83c\udde8\", \"\ud83c\uddfb\ud83c\udde8: vc, vct, SaintVincent, NORTHAMERICA\" }, \/\/ Saint Vincent and the Grenadines\n  { \"\ud83c\uddfa\ud83c\uddf8\", \"\ud83c\uddfa\ud83c\uddf8: us, usa, UnitedStatesofAmerica, USA, NORTHAMERICA\" }, \/\/ United States of America\n  { \"\ud83c\uddfb\ud83c\uddee\", \"\ud83c\uddfb\ud83c\uddee: vi, vir, VirginIslands, USA, NORTHAMERICA\" }, \/\/ United States Virgin Islands\n\n  { \"\ud83c\udde7\ud83c\uddfb\", \"\ud83c\udde7\ud83c\uddfb: bv, bvt, BouvetIsland\" }, \/\/ Bouvet Island\n  { \"\ud83c\uddfa\ud83c\uddf2\", \"\ud83c\uddfa\ud83c\uddf2: um, umi, Navassa\" },\n  { \"\ud83c\uddf8\ud83c\udded\", \"\ud83c\uddf8\ud83c\udded: sh, shn, SaintHelena\" }, \/\/ Saint Helena\n  \n  { \"\ud83c\udde6\ud83c\uddf7\", \"\ud83c\udde6\ud83c\uddf7: ar, arg, Argentina, SOUTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf4\", \"\ud83c\udde7\ud83c\uddf4: bo, bol, Bolivia, SOUTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf7\", \"\ud83c\udde7\ud83c\uddf7: br, bra, Brazil, SOUTHAMERICA, BRICS\" },\n  { \"\ud83c\udde8\ud83c\uddf1\", \"\ud83c\udde8\ud83c\uddf1: cl, chl, Chile, SOUTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddf4\", \"\ud83c\udde8\ud83c\uddf4: co, col, Colombia, SOUTHAMERICA\" },\n  { \"\ud83c\uddea\ud83c\udde8\", \"\ud83c\uddea\ud83c\udde8: ec, ecu, Ecuador, SOUTHAMERICA\" },\n  { \"\ud83c\uddeb\ud83c\uddf0\", \"\ud83c\uddeb\ud83c\uddf0: fk, flk, FalklandIslands, UK, SOUTHAMERICA\" }, \/\/ Falkland Islands\n  { \"\ud83c\uddec\ud83c\uddeb\", \"\ud83c\uddec\ud83c\uddeb: gf, guf, FrenchGuiana, SOUTHAMERICA, FRANCE\" }, \/\/ French Guiana\n  { \"\ud83c\uddec\ud83c\uddfe\", \"\ud83c\uddec\ud83c\uddfe: gy, guy, Guyana, SOUTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddfe\", \"\ud83c\uddf5\ud83c\uddfe: py, pry, Paraguay, SOUTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddea\", \"\ud83c\uddf5\ud83c\uddea: pe, per, Peru, SOUTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf8\", \"\ud83c\uddec\ud83c\uddf8: gs, sgs, SouthGeorgia, SOUTHAMERICA\" }, \/\/ South Georgia and the South Sandwich Islands\n  { \"\ud83c\uddf8\ud83c\uddf7\", \"\ud83c\uddf8\ud83c\uddf7: sr, sur, Suriname, SOUTHAMERICA\" },\n  { \"\ud83c\uddfa\ud83c\uddfe\", \"\ud83c\uddfa\ud83c\uddfe: uy, ury, Uruguay, SOUTHAMERICA\" },\n  { \"\ud83c\uddfb\ud83c\uddea\", \"\ud83c\uddfb\ud83c\uddea: ve, ven, Venezuela, SOUTHAMERICA\" },\n\n  { \"\ud83c\udde6\ud83c\uddea\", \"\ud83c\udde6\ud83c\uddea: ae, are, UnitedArabEmirates, WESTASIA, ASIA, EURASIA\" }, \/\/ United Arab Emirates\n  { \"\ud83c\udde6\ud83c\uddeb\", \"\ud83c\udde6\ud83c\uddeb: af, afg, Afghanistan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udde9\", \"\ud83c\udde7\ud83c\udde9: bd, bgd, Bangladesh, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udded\", \"\ud83c\udde7\ud83c\udded: bh, bhr, Bahrain, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddf3\", \"\ud83c\udde7\ud83c\uddf3: bn, brn, Brunei, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddf9\", \"\ud83c\udde7\ud83c\uddf9: bt, btn, Bhutan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\uddf3\", \"\ud83c\udde8\ud83c\uddf3: cn, chn, China, EASTASIA, ASIA, EURASIA, BRICS\" },\n  { \"\ud83c\udded\ud83c\uddf0\", \"\ud83c\udded\ud83c\uddf0: hk, hkg, HongKong, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\udde9\", \"\ud83c\uddee\ud83c\udde9: id, idn, Indonesia, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf1\", \"\ud83c\uddee\ud83c\uddf1: il, isr, Israel, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf3\", \"\ud83c\uddee\ud83c\uddf3: in, ind, India, SOUTHASIA, ASIA, EURASIA, BRICS\" },\n  { \"\ud83c\uddee\ud83c\uddf6\", \"\ud83c\uddee\ud83c\uddf6: iq, irq, Iraq, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf7\", \"\ud83c\uddee\ud83c\uddf7: ir, irn, Iran, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddef\ud83c\uddf4\", \"\ud83c\uddef\ud83c\uddf4: jo, jor, Jordan, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddef\ud83c\uddf5\", \"\ud83c\uddef\ud83c\uddf5: jp, jpn, Japan, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddec\", \"\ud83c\uddf0\ud83c\uddec: kg, kgz, Kyrgyzstan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\udded\", \"\ud83c\uddf0\ud83c\udded: kh, khm, Cambodia, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddf7\", \"\ud83c\uddf0\ud83c\uddf7: kr, kor, SouthKorea, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddfc\", \"\ud83c\uddf0\ud83c\uddfc: kw, kwt, Kuwait, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\udde6\", \"\ud83c\uddf1\ud83c\udde6: la, lao, Laos, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\udde7\", \"\ud83c\uddf1\ud83c\udde7: lb, lbn, Lebanon, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddf0\", \"\ud83c\uddf1\ud83c\uddf0: lk, lka, SriLanka, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf3\", \"\ud83c\uddf2\ud83c\uddf3: mn, mng, Mongolia, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf4\", \"\ud83c\uddf2\ud83c\uddf4: mo, mac, Macao, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddfb\", \"\ud83c\uddf2\ud83c\uddfb: mv, mdv, Maldives, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf2\", \"\ud83c\uddf2\ud83c\uddf2: mm, mmr, Myanmar, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddfe\", \"\ud83c\uddf2\ud83c\uddfe: my, mys, Malaysia, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddf5\", \"\ud83c\uddf0\ud83c\uddf5: kp, prk, NorthKorea, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf5\", \"\ud83c\uddf3\ud83c\uddf5: np, npl, Nepal, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf4\ud83c\uddf2\", \"\ud83c\uddf4\ud83c\uddf2: om, omn, Oman, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\udded\", \"\ud83c\uddf5\ud83c\udded: ph, phl, Philippines, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf0\", \"\ud83c\uddf5\ud83c\uddf0: pk, pak, Pakistan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf8\", \"\ud83c\uddf5\ud83c\uddf8: ps, pse, Palestine, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf6\ud83c\udde6\", \"\ud83c\uddf6\ud83c\udde6: qa, qat, Qatar, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\udde6\", \"\ud83c\uddf8\ud83c\udde6: sa, sau, SaudiArabia, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddec\", \"\ud83c\uddf8\ud83c\uddec: sg, sgb, Singapore, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddfe\", \"\ud83c\uddf8\ud83c\uddfe: sy, syr, Syria, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\udded\", \"\ud83c\uddf9\ud83c\udded: th, tha, Thailand, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddef\", \"\ud83c\uddf9\ud83c\uddef: tj, tjk, Tajikistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf1\", \"\ud83c\uddf9\ud83c\uddf1: tl, tls, EastTimor, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf2\", \"\ud83c\uddf9\ud83c\uddf2: tm, tkm, Turkmenistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddfc\", \"\ud83c\uddf9\ud83c\uddfc: tw, twn, Taiwan, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddfa\ud83c\uddff\", \"\ud83c\uddfa\ud83c\uddff: uz, uzb, Uzbekistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddfb\ud83c\uddf3\", \"\ud83c\uddfb\ud83c\uddf3: vn, vnm, Vietnam, ASIA, EURASIA\" },\n  { \"\ud83c\uddfe\ud83c\uddea\", \"\ud83c\uddfe\ud83c\uddea: ye, yem, Yemen, WESTASIA, ASIA, EURASIA\" },\n\n  { \"\ud83c\uddf3\ud83c\uddea\", \"\ud83c\uddf3\ud83c\uddea: ne, ner, Nigeria, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf9\", \"\ud83c\uddea\ud83c\uddf9: et, eth, Ethiopia, AFRICA, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf7\", \"\ud83c\uddea\ud83c\uddf7: er, eri, Eritrea, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddec\", \"\ud83c\udde8\ud83c\uddec: cg, cog, Congo, AFRICA, CENTRALAFRICA\" }, \/\/ Rebublic of the Congo\n  { \"\ud83c\udde8\ud83c\udde9\", \"\ud83c\udde8\ud83c\udde9: cd, cod, DemocraticCongo, AFRICA, CENTRALAFRICA\" }, \/\/ Democratic Rebublic of the Congo\n  { \"\ud83c\uddf9\ud83c\uddff\", \"\ud83c\uddf9\ud83c\uddff: tz, tza, Tanzania, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\udde6\", \"\ud83c\uddff\ud83c\udde6: za, zaf, SouthAfrica, AFRICA, SOUTHAFRICA, BRICS\" },\n  { \"\ud83c\uddf0\ud83c\uddea\", \"\ud83c\uddf0\ud83c\uddea: ke, ken, Kenya, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddfa\ud83c\uddec\", \"\ud83c\uddfa\ud83c\uddec: ug, uga, Uganda, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf8\", \"\ud83c\uddf8\ud83c\uddf8: ss, ssd, SouthSudan, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\udde9\", \"\ud83c\uddf8\ud83c\udde9: sd, sdn, Sudan, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde9\ud83c\uddff\", \"\ud83c\udde9\ud83c\uddff: dz, dza, Algeria, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddec\", \"\ud83c\uddea\ud83c\uddec: eg, egy, Egypt, AFRICA, NORTHAFRICA, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddfe\", \"\ud83c\uddf1\ud83c\uddfe: ly, lby, Libya, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf1\ud83c\uddfe\", \"\ud83c\uddf1\ud83c\uddfe: ly, lby, Madeira, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\udde6\", \"\ud83c\uddf2\ud83c\udde6: ma, mar, Morocco, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\udde6\ud83c\uddf4\", \"\ud83c\udde6\ud83c\uddf4: ao, ago, Angola, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddec\ud83c\udded\", \"\ud83c\uddec\ud83c\udded: gh, gha, Ghana, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddff\", \"\ud83c\uddf2\ud83c\uddff: mz, moz, Mozambique, AFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddec\", \"\ud83c\uddf2\ud83c\uddec: mg, mdg, Madagascar, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddfe\ud83c\uddf9\", \"\ud83c\uddfe\ud83c\uddf9: yt, myt, Mayotte, FRANCE, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddee\", \"\ud83c\udde8\ud83c\uddee: ci, civ, IvoryCoast, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddf2\", \"\ud83c\udde8\ud83c\uddf2: cm, cmr, Cameroon, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf3\ud83c\uddea\", \"\ud83c\uddf3\ud83c\uddea: ne, ner, Niger, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddeb\", \"\ud83c\udde7\ud83c\uddeb: bf, bfa, BurkinaFaso, AFRICA, WESTAFRICA\" }, \/\/ Burkina Faso\n  { \"\ud83c\uddf2\ud83c\uddf1\", \"\ud83c\uddf2\ud83c\uddf1: ml, mli, Mali, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfc\", \"\ud83c\uddf2\ud83c\uddfc: mw, mwi, Malawi, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\uddf2\", \"\ud83c\uddff\ud83c\uddf2: zm, zmb, Zambia, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\udde9\", \"\ud83c\uddf9\ud83c\udde9: td, tcd, Chad, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf4\", \"\ud83c\uddf8\ud83c\uddf4: so, som, Somalia, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf3\", \"\ud83c\uddf8\ud83c\uddf3: sn, sen, Senegal, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\uddfc\", \"\ud83c\uddff\ud83c\uddfc: zw, zwe, Zimbabwe, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddf3\", \"\ud83c\uddec\ud83c\uddf3: gn, gin, Guinea, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf7\ud83c\uddea\", \"\ud83c\uddf7\ud83c\uddea: re, reu, R\u00e9union, reunion, FRANCE, AFRICA, EASTAFRICA\" }, \/\/ R\u00e9union\n  { \"\ud83c\uddf7\ud83c\uddfc\", \"\ud83c\uddf7\ud83c\uddfc: rw, rwa, Rwanda, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddef\", \"\ud83c\udde7\ud83c\uddef: bj, ben, Benin, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddee\", \"\ud83c\udde7\ud83c\uddee: bi, bdi, Burundi, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\uddf3\", \"\ud83c\uddf9\ud83c\uddf3: tn, tun, Tunisia, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\uddec\", \"\ud83c\uddf9\ud83c\uddec: tg, tgo, Togo, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf1\", \"\ud83c\uddf8\ud83c\uddf1: sl, sle, SierraLeone, AFRICA, WESTAFRICA\" }, \/\/ Sierra Leone\n  { \"\ud83c\udde8\ud83c\udde9\", \"\ud83c\udde8\ud83c\udde9: cd, cod, Congo, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddeb\", \"\ud83c\udde8\ud83c\uddeb: cf, caf, CentralAfrican, CENTRALAFRICA\" }, \/\/ Central African Republic\n  { \"\ud83c\uddf1\ud83c\uddf7\", \"\ud83c\uddf1\ud83c\uddf7: lr, lbr, Liberia, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf7\", \"\ud83c\uddf2\ud83c\uddf7: mr, mrt, Mauritania, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf7\", \"\ud83c\uddea\ud83c\uddf7: er, eri, Eritrea, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddf2\", \"\ud83c\uddec\ud83c\uddf2: gm, gmb, Gambia, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddfc\", \"\ud83c\udde7\ud83c\uddfc: bw, bwa, Botswana, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddf3\ud83c\udde6\", \"\ud83c\uddf3\ud83c\udde6: na, nam, Namibia, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddec\ud83c\udde6\", \"\ud83c\uddec\ud83c\udde6: ga, gab, Gabon, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf1\ud83c\uddf8\", \"\ud83c\uddf1\ud83c\uddf8: ls, lso, Lesotho, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddfc\", \"\ud83c\uddec\ud83c\uddfc: gw, gnb, GuineaBissau, AFRICA, WESTAFRICA\" }, \/\/ Guinea-Bissau\n  { \"\ud83c\uddec\ud83c\uddf6\", \"\ud83c\uddec\ud83c\uddf6: gq, gnq, EquatorialGuinea, CENTRALAFRICA\" }, \/\/ Equatorial Guinea\n  { \"\ud83c\uddf2\ud83c\uddfa\", \"\ud83c\uddf2\ud83c\uddfa: mu, mus, Mauritius, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfa\", \"\ud83c\uddf2\ud83c\uddfa: mz, moz, Mozambique, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddff\", \"\ud83c\uddf8\ud83c\uddff: sz, swz, Eswatini, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\udde9\ud83c\uddef\", \"\ud83c\udde9\ud83c\uddef: dj, dji, Djibouti, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf0\ud83c\uddf2\", \"\ud83c\uddf0\ud83c\uddf2: km, com, Comoros, AFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddfb\", \"\ud83c\udde8\ud83c\uddfb: cv, cpv, CapeVerde, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\udded\", \"\ud83c\uddea\ud83c\udded: eh, esh, WesternSahara, SPAIN, AFRICA, NORTHAFRICA\" }, \/\/ Western Sahara\n  { \"\ud83c\uddf8\ud83c\uddf9\", \"\ud83c\uddf8\ud83c\uddf9: st, stp, S\u00e3oTom\u00e9andPr\u00edncipe, saotomeandprincipe, CENTRALAFRICA\" }, \/\/ S\u00e3o Tom\u00e9 and Pr\u00edncipe\n  { \"\ud83c\uddf8\ud83c\udde8\", \"\ud83c\uddf8\ud83c\udde8: sc, syc, Seychelles, AFRICA, EASTAFRICA\" },\n\n  { \"\ud83c\uddf8\ud83c\udded\", \"\ud83c\uddf8\ud83c\udded: sh, shn, TristandaCunha, UK\" }, \/\/ Tristan da Cunha\n  \n  { \"\ud83c\udde6\ud83c\uddfa\", \"\ud83c\udde6\ud83c\uddfa: au, aus, Australia, AUSTRALASIA, OCEANIA\" },\n  { \"\ud83c\udde8\ud83c\uddfd\", \"\ud83c\udde8\ud83c\uddfd: cx, cxr, Christmasisland, AUSTRALIA\" }, \/\/ Christmas Island\n\n  { \"\ud83c\udde8\ud83c\udde8\", \"\ud83c\udde8\ud83c\udde8: cc, cck, CocosIslands, AUSTRALIA\" }, \/\/ Cocos (Keeling) Islands\n  \n  { \"\ud83c\uddee\ud83c\uddf2\", \"\ud83c\uddee\ud83c\uddf2: im, imn, ManIsle, UK\" }, \/\/ Isle of Man\n  \n  { \"\ud83c\uddf0\ud83c\uddee\", \"\ud83c\uddf0\ud83c\uddee: ki, kir, Kiribati, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf7\", \"\ud83c\uddf3\ud83c\uddf7: nr, nru, Nauru, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf3\ud83c\udde8\", \"\ud83c\uddf3\ud83c\udde8: nc, ncl, NewCaledonia, FRANCE, OCEANIA\" }, \/\/ New Caledonia\n  { \"\ud83c\uddeb\ud83c\uddef\", \"\ud83c\uddeb\ud83c\uddef: fj, fji, Fiji, MELANESIA, OCEANIA\" },\n  { \"\ud83c\uddeb\ud83c\uddf2\", \"\ud83c\uddeb\ud83c\uddf2: fm, fsm, Micronesia, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf5\ud83c\uddec\", \"\ud83c\uddf5\ud83c\uddec: pg, png, PapuanewGuinea, MELANESIA, OCEANIA\" }, \/\/ Papua New Guinea\n  { \"\ud83c\uddfb\ud83c\uddfa\", \"\ud83c\uddfb\ud83c\uddfa: vu, vut, Vanuatu, MELANESIA, OCEANIA\" },\n  { \"\ud83c\uddf8\ud83c\udde7\", \"\ud83c\uddf8\ud83c\udde7: sb, slb, SolomonIslands, MELANESIA, OCEANIA\" }, \/\/ Solomon Islands\n  { \"\ud83c\uddec\ud83c\uddfa\", \"\ud83c\uddec\ud83c\uddfa: gu, gum, Guam, USA, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf2\ud83c\udded\", \"\ud83c\uddf2\ud83c\udded: mh, mhl, MarshallIslands, MICRONESIA, OCEANIA\" }, \/\/ Marshall Islands\n  { \"\ud83c\uddf2\ud83c\uddf5\", \"\ud83c\uddf2\ud83c\uddf5: mp, mnp, NorthernMariana, MICRONESIA, OCEANIA\" }, \/\/ Northern Mariana Islands\n  { \"\ud83c\uddf5\ud83c\uddeb\", \"\ud83c\uddf5\ud83c\uddeb: pf, pyf, FrenchPolynesia, FRANCE, POLYNESIA, OCEANIA\" }, \/\/ French Polynesia\n  { \"\ud83c\uddfc\ud83c\uddf8\", \"\ud83c\uddfc\ud83c\uddf8: ws, wsm, Samoa, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddfc\ud83c\uddeb\", \"\ud83c\uddfc\ud83c\uddeb: wf, wlf, WallisandFutuna, FRANCE, OCEANIA\" }, \/\/ Wallis and Futuna\n  { \"\ud83c\uddf9\ud83c\uddfb\", \"\ud83c\uddf9\ud83c\uddfb: tv, tuv, Tuvalu, OCEANIA\" },\n  { \"\ud83c\udde6\ud83c\uddf8\", \"\ud83c\udde6\ud83c\uddf8: as, asm, Americansamoa, USA, POLYNESIA, OCEANIA\" }, \/\/ American Samoa\n  { \"\ud83c\uddf5\ud83c\uddf3\", \"\ud83c\uddf5\ud83c\uddf3: pn, pcn, Pitcairn, UK, POLYNESIA, OCEANIA\" }, \/\/ Pitcairn Islands\n  { \"\ud83c\uddf5\ud83c\uddfc\", \"\ud83c\uddf5\ud83c\uddfc: pw, plw, Palau, MICRONESIA, OCEANIA\" },\n\n  { \"\ud83c\uddef\ud83c\uddea\", \"\ud83c\uddef\ud83c\uddea: je, jey, Jersey, FRANCE\" },\n  \n  { \"\ud83c\udde6\ud83c\uddf6\", \"\ud83c\udde6\ud83c\uddf6: aq, ata, Antarctica, ANTARCTICA\" },\n\n  { \"\ud83c\uddf3\ud83c\uddeb\", \"\ud83c\uddf3\ud83c\uddeb: nf, nfk, NorFolkIsland, AUSTRALASIA, POLYNESIA, OCEANIA\" }, \/\/ Norfolk Island\n  { \"\ud83c\udde8\ud83c\uddf0\", \"\ud83c\udde8\ud83c\uddf0: ck, cok, Cookisland, NEWZEALAND, POLYNESIA, OCEANIA\" }, \/\/ Cook Islands\n  { \"\ud83c\uddf3\ud83c\uddff\", \"\ud83c\uddf3\ud83c\uddff: nz, nzl, NewZealand, NEWZEALAND, AUSTRALASIA, OCEANIA\" }, \/\/ New Zealand\n  { \"\ud83c\uddf3\ud83c\uddfa\", \"\ud83c\uddf3\ud83c\uddfa: nu, niu, Niue, NEWZEALAND, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf0\", \"\ud83c\uddf9\ud83c\uddf0: tk, tkl, Tokelau, NEWZEALAND, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf4\", \"\ud83c\uddf9\ud83c\uddf4: to, ton, Tonga, POLYNESIA, OCEANIA\" },\n  \n  \/\/ still missing\n  \n  { \"\ud83c\uddee\ud83c\uddf4\", \"\ud83c\uddee\ud83c\uddf4: io, iot, BritishIndianOcean\" }, \/\/ British Indian Ocean Territory\n  { \"\ud83c\uddf9\ud83c\uddeb\", \"\ud83c\uddf9\ud83c\uddeb: tf, atf, FrenchSouthernandaAtarctic\" }, \/\/ French Southern and Antarctic Lands\n  { \"\ud83c\uddec\ud83c\uddec\", \"\ud83c\uddec\ud83c\uddec: gg, ggy, Guernsey, GUERNSEY\" },\n  { \"\ud83c\udded\ud83c\uddf2\", \"\ud83c\udded\ud83c\uddf2: hm, hmd, HeardandMacDonaldsIslands\" }, \/\/ Heard Island and McDonald Islands\n  { \"\ud83c\uddfa\ud83c\uddf2\", \"\ud83c\uddfa\ud83c\uddf2: um, umi, UsMinorOutlyingIslands, US\" }, \/\/ United States Minor Outlying Islands\n};<\/code><\/pre>\n\n\n\n<p>Edit: N\u00e4m\u00e4 liput taitaa olla suurempi projeksi. Lis\u00e4tty t\u00e4h\u00e4n alkuun lippujen DEBUG77 tuloste, ett\u00e4 sekin l\u00f6ytyy helposti.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>area:FINLAND, Finland(fi), \u00c5land(ax), count:2\narea:DENMARK, Denmark(dk), FaroeIslands(fo), Greenland(gl), Greenland(gl), count:4\narea:NORDIC, Finland(fi), \u00c5land(ax), Sweden(se), Norway(no), Denmark(dk), FaroeIslands(fo), Iceland(is), Greenland(gl), count:8\narea:BALTIC, Estonia(ee), Latvia(lv), Lithuania(lt), count:3\narea:FRANCE, ClippertonIsland(fr), Guadeloupe(gp), Martinique(mq), FrenchGuiana(gf), Mayotte(yt), R\u00e9union(re), NewCaledonia(nc), FrenchPolynesia(pf), WallisandFutuna(wf), Jersey(je), count:10\narea:UK, Ireland(ie), UnitedKingdom(gb), England(gb), Scotland(gb), Wales(gb), Gibraltar(gi), Anguilla(ai), Bermuda(bm), BritishVirginIslands(vg), CaymanIslands(ky), Montserrat(ms), TurksandCaicos(tc), FalklandIslands(fk), TristandaCunha(sh), ManIsle(im), Pitcairn(pn), count:16\narea:SPAIN, WesternSahara(eh), count:1\narea:EU, Finland(fi), Sweden(se), Denmark(dk), Estonia(ee), Latvia(lv), Lithuania(lt), Austria(at), Belgium(be), Bulgaria(bg), Croatia(hr), Cyprus(cy), CzechRepublic(cz), France(fr), Germany(de), Greece(gr), Hungary(hu), Ireland(ie), Italy(it), Luxembourg(lu), Malta(mt), Netherlands(nl), Poland(pl), Portugal(pt), Romania(ro), Slovakia(sk), Slovenia(si), Spain(es), Switzerland(ch), count:28\narea:NORTHERNEUROPE, Finland(fi), Sweden(se), Norway(no), Denmark(dk), Iceland(is), Estonia(ee), Latvia(lv), Lithuania(lt), count:8\narea:EASTERNEUROPE, Ukraine(ua), Albania(al), Armenia(am), Azerbaijan(az), Belarus(by), BosniaandHerzegovina(ba), Bulgaria(bg), Croatia(hr), CzechRepublic(cz), Georgia(ge), Hungary(hu), Moldova(md), Montenegro(me), Northmacedonia(mk), Poland(pl), Romania(ro), Russia(ru), Serbia(rs), Slovakia(sk), Slovenia(si), count:20\narea:SOUTHERNEUROPE, Cyprus(cy), Greece(gr), Italy(it), Vatican(va), Malta(mt), Portugal(pt), SanMarino(sm), Spain(es), Turkey(tr), count:9\narea:WESTERNEUROPE, Andorra(ad), Austria(at), Belgium(be), France(fr), Germany(de), Ireland(ie), Liechtenstein(li), Luxembourg(lu), Monaco(mc), Netherlands(nl), Switzerland(ch), UnitedKingdom(gb), count:12\narea:EUROPE, Finland(fi), Sweden(se), Norway(no), Denmark(dk), Iceland(is), Estonia(ee), Latvia(lv), Lithuania(lt), Ukraine(ua), Albania(al), Andorra(ad), Armenia(am), Austria(at), Azerbaijan(az), Belarus(by), Belgium(be), BosniaandHerzegovina(ba), Bulgaria(bg), Croatia(hr), Cyprus(cy), CzechRepublic(cz), France(fr), Georgia(ge), Germany(de), Greece(gr), Hungary(hu), Ireland(ie), Italy(it), Vatican(va), Kazakhstan(kz), Liechtenstein(li), Luxembourg(lu), Malta(mt), Moldova(md), Montenegro(me), Monaco(mc), Montenegro(me), Netherlands(nl), Northmacedonia(mk), Poland(pl), Portugal(pt), Romania(ro), Russia(ru), SanMarino(sm), Serbia(rs), Slovakia(sk), Slovenia(si), Spain(es), Switzerland(ch), Turkey(tr), UnitedKingdom(gb), count:51\narea:EURASIA, Finland(fi), Sweden(se), Norway(no), Denmark(dk), Iceland(is), Estonia(ee), Latvia(lv), Lithuania(lt), Ukraine(ua), Albania(al), Andorra(ad), Armenia(am), Austria(at), Azerbaijan(az), Belarus(by), Belgium(be), Bulgaria(bg), Croatia(hr), Cyprus(cy), CzechRepublic(cz), France(fr), Georgia(ge), Germany(de), Greece(gr), Hungary(hu), Ireland(ie), Italy(it), Vatican(va), Kazakhstan(kz), Liechtenstein(li), Luxembourg(lu), Malta(mt), Moldova(md), Montenegro(me), Monaco(mc), Montenegro(me), Netherlands(nl), Northmacedonia(mk), Poland(pl), Portugal(pt), Romania(ro), Russia(ru), SanMarino(sm), Serbia(rs), Slovakia(sk), Slovenia(si), Spain(es), Switzerland(ch), Turkey(tr), UnitedKingdom(gb), UnitedArabEmirates(ae), Afghanistan(af), Bangladesh(bd), Bahrain(bh), Brunei(bn), Bhutan(bt), China(cn), HongKong(hk), Indonesia(id), Israel(il), India(in), Iraq(iq), Iran(ir), Jordan(jo), Japan(jp), Kyrgyzstan(kg), Cambodia(kh), SouthKorea(kr), Kuwait(kw), Laos(la), Lebanon(lb), SriLanka(lk), Mongolia(mn), Macao(mo), Maldives(mv), Myanmar(mm), Malaysia(my), NorthKorea(kp), Nepal(np), Oman(om), Philippines(ph), Pakistan(pk), Palestine(ps), Qatar(qa), SaudiArabia(sa), Singapore(sg), Syria(sy), Thailand(th), Tajikistan(tj), EastTimor(tl), Turkmenistan(tm), Taiwan(tw), Uzbekistan(uz), Vietnam(vn), Yemen(ye), Egypt(eg), count:96\narea:NORTHASIA, Russia(ru), count:1\narea:EASTASIA, Bahrain(bh), China(cn), HongKong(hk), Japan(jp), SouthKorea(kr), Mongolia(mn), Macao(mo), NorthKorea(kp), Taiwan(tw), count:9\narea:CENTRALASIA, Kazakhstan(kz), Kyrgyzstan(kg), Tajikistan(tj), Turkmenistan(tm), Uzbekistan(uz), count:5\narea:SOUTHASIA, Afghanistan(af), Bangladesh(bd), Bhutan(bt), India(in), SriLanka(lk), Maldives(mv), Nepal(np), Pakistan(pk), count:8\narea:WESTASIA, Armenia(am), Azerbaijan(az), Cyprus(cy), Georgia(ge), Turkey(tr), UnitedArabEmirates(ae), Israel(il), Iraq(iq), Iran(ir), Jordan(jo), Kuwait(kw), Lebanon(lb), Oman(om), Palestine(ps), Qatar(qa), SaudiArabia(sa), Syria(sy), Yemen(ye), Egypt(eg), count:19\narea:ASIA, Armenia(am), Azerbaijan(az), Cyprus(cy), Georgia(ge), Kazakhstan(kz), Russia(ru), Turkey(tr), UnitedArabEmirates(ae), Afghanistan(af), Bangladesh(bd), Bahrain(bh), Brunei(bn), Bhutan(bt), China(cn), HongKong(hk), Indonesia(id), Israel(il), India(in), Iraq(iq), Iran(ir), Jordan(jo), Japan(jp), Kyrgyzstan(kg), Cambodia(kh), SouthKorea(kr), Kuwait(kw), Laos(la), Lebanon(lb), SriLanka(lk), Mongolia(mn), Macao(mo), Maldives(mv), Myanmar(mm), Malaysia(my), NorthKorea(kp), Nepal(np), Oman(om), Philippines(ph), Pakistan(pk), Palestine(ps), Qatar(qa), SaudiArabia(sa), Singapore(sg), Syria(sy), Thailand(th), Tajikistan(tj), EastTimor(tl), Turkmenistan(tm), Taiwan(tw), Uzbekistan(uz), Vietnam(vn), Yemen(ye), Egypt(eg), count:53\narea:NORTHAFRICA, Algeria(dz), Egypt(eg), Libya(ly), Madeira(ly), Morocco(ma), Tunisia(tn), WesternSahara(eh), count:7\narea:EASTAFRICA, Ethiopia(et), Eritrea(er), Tanzania(tz), Kenya(ke), Uganda(ug), SouthSudan(ss), Sudan(sd), Madagascar(mg), Mayotte(yt), Malawi(mw), Zambia(zm), Somalia(so), Zimbabwe(zw), R\u00e9union(re), Rwanda(rw), Burundi(bi), Eritrea(er), Mauritius(mu), Mozambique(mz), Djibouti(dj), Seychelles(sc), count:21\narea:CENTRALAFRICA, Congo(cg), DemocraticCongo(cd), Angola(ao), Cameroon(cm), Chad(td), Congo(cd), CentralAfrican(cf), Gabon(ga), EquatorialGuinea(gq), S\u00e3oTom\u00e9andPr\u00edncipe(st), count:10\narea:SOUTHAFRICA, SouthAfrica(za), Botswana(bw), Namibia(na), Lesotho(ls), Eswatini(sz), count:5\narea:WESTAFRICA, Nigeria(ne), Ghana(gh), IvoryCoast(ci), Niger(ne), BurkinaFaso(bf), Mali(ml), Senegal(sn), Guinea(gn), Benin(bj), Togo(tg), SierraLeone(sl), Liberia(lr), Mauritania(mr), Gambia(gm), GuineaBissau(gw), CapeVerde(cv), count:16\narea:AFRICA, Nigeria(ne), Ethiopia(et), Eritrea(er), Congo(cg), DemocraticCongo(cd), Tanzania(tz), SouthAfrica(za), Kenya(ke), Uganda(ug), SouthSudan(ss), Sudan(sd), Algeria(dz), Egypt(eg), Libya(ly), Madeira(ly), Morocco(ma), Angola(ao), Ghana(gh), Mozambique(mz), Madagascar(mg), Mayotte(yt), IvoryCoast(ci), Cameroon(cm), Niger(ne), BurkinaFaso(bf), Mali(ml), Malawi(mw), Zambia(zm), Chad(td), Somalia(so), Senegal(sn), Zimbabwe(zw), Guinea(gn), R\u00e9union(re), Rwanda(rw), Benin(bj), Burundi(bi), Tunisia(tn), Togo(tg), SierraLeone(sl), Congo(cd), Liberia(lr), Mauritania(mr), Eritrea(er), Gambia(gm), Botswana(bw), Namibia(na), Gabon(ga), Lesotho(ls), GuineaBissau(gw), Mauritius(mu), Mozambique(mz), Eswatini(sz), Djibouti(dj), Comoros(km), CapeVerde(cv), WesternSahara(eh), Seychelles(sc), count:58\narea:NORTHAMERICA, Greenland(gl), Anguilla(ai), AntiguaAndBarbuda(ag), Aruba(aw), Bahamas(bs), Barbados(bb), Belize(bz), Bermuda(bm), Bonaire(bq), BritishVirginIslands(vg), Canada(ca), CaymanIslands(ky), ClippertonIsland(fr), CostaRica(cr), Cuba(cu), Cura\u00e7ao(cw), Dominica(dm), DominicanRepublic(do), ElSalvador(sv), Greenland(gl), Grenada(gd), Guadeloupe(gp), Guatemala(gt), Haiti(ht), Honduras(hn), Jamaica(jm), Martinique(mq), Mexico(mx), Montserrat(ms), Nicaragua(ni), Panama(pa), PuertoRico(pr), Saba(bq), SaintBarth\u00e9lemy(bl), SaintKitts(kn), SaintLucia(lc), SaintMartin(mf), SintMaarten(sx), TrinidadandTobago(tt), TurksandCaicos(tc), SaintPierre(pm), SaintVincent(vc), UnitedStatesofAmerica(us), VirginIslands(vi), count:44\narea:SOUTHAMERICA, Argentina(ar), Bolivia(bo), Brazil(br), Chile(cl), Colombia(co), Ecuador(ec), FalklandIslands(fk), FrenchGuiana(gf), Guyana(gy), Paraguay(py), Peru(pe), SouthGeorgia(gs), Suriname(sr), Uruguay(uy), Venezuela(ve), count:15\narea:USA, UnitedStatesofAmerica(us), VirginIslands(vi), Guam(gu), Americansamoa(as), count:4\narea:OCEANIA, Australia(au), Kiribati(ki), Nauru(nr), NewCaledonia(nc), Fiji(fj), Micronesia(fm), PapuanewGuinea(pg), Vanuatu(vu), SolomonIslands(sb), Guam(gu), MarshallIslands(mh), NorthernMariana(mp), FrenchPolynesia(pf), Samoa(ws), WallisandFutuna(wf), Tuvalu(tv), Americansamoa(as), Pitcairn(pn), Palau(pw), NorFolkIsland(nf), Cookisland(ck), NewZealand(nz), Niue(nu), Tokelau(tk), Tonga(to), count:25\narea:AUSTRALASIA, Australia(au), NorFolkIsland(nf), NewZealand(nz), count:3\narea:MELANESIA, Fiji(fj), PapuanewGuinea(pg), Vanuatu(vu), SolomonIslands(sb), count:4\narea:MICRONESIA, Kiribati(ki), Nauru(nr), Micronesia(fm), Guam(gu), MarshallIslands(mh), NorthernMariana(mp), Palau(pw), count:7\narea:POLYNESIA, FrenchPolynesia(pf), Samoa(ws), Americansamoa(as), Pitcairn(pn), NorFolkIsland(nf), Cookisland(ck), Niue(nu), Tokelau(tk), Tonga(to), count:9\narea:BRICS, Russia(ru), Brazil(br), China(cn), India(in), SouthAfrica(za), count:5\narea:ALL, Finland(fi), \u00c5land(ax), Sweden(se), Norway(no), Denmark(dk), FaroeIslands(fo), Iceland(is), Greenland(gl), Estonia(ee), Latvia(lv), Lithuania(lt), Ukraine(ua), Albania(al), Andorra(ad), Armenia(am), Austria(at), Azerbaijan(az), Belarus(by), Belgium(be), BosniaandHerzegovina(ba), Bulgaria(bg), Croatia(hr), Cyprus(cy), CzechRepublic(cz), France(fr), Georgia(ge), Germany(de), Greece(gr), Hungary(hu), Ireland(ie), Italy(it), Vatican(va), Kazakhstan(kz), Liechtenstein(li), Luxembourg(lu), Malta(mt), Moldova(md), Montenegro(me), Monaco(mc), Montenegro(me), Netherlands(nl), Northmacedonia(mk), Poland(pl), Portugal(pt), Romania(ro), Russia(ru), SanMarino(sm), Serbia(rs), Slovakia(sk), Slovenia(si), Spain(es), Switzerland(ch), Turkey(tr), UnitedKingdom(gb), England(gb), Scotland(gb), Wales(gb), Gibraltar(gi), JanMayen(sj), Anguilla(ai), AntiguaAndBarbuda(ag), Aruba(aw), Bahamas(bs), Barbados(bb), Belize(bz), Bermuda(bm), Bonaire(bq), BritishVirginIslands(vg), Canada(ca), CaymanIslands(ky), ClippertonIsland(fr), CostaRica(cr), Cuba(cu), Cura\u00e7ao(cw), Dominica(dm), DominicanRepublic(do), ElSalvador(sv), Greenland(gl), Grenada(gd), Guadeloupe(gp), Guatemala(gt), Haiti(ht), Honduras(hn), Jamaica(jm), Martinique(mq), Mexico(mx), Montserrat(ms), Nicaragua(ni), Panama(pa), PuertoRico(pr), Saba(bq), SaintBarth\u00e9lemy(bl), SaintKitts(kn), SaintLucia(lc), SaintMartin(mf), SintMaarten(sx), TrinidadandTobago(tt), TurksandCaicos(tc), SaintPierre(pm), SaintVincent(vc), UnitedStatesofAmerica(us), VirginIslands(vi), BouvetIsland(bv), Navassa(um), SaintHelena(sh), Argentina(ar), Bolivia(bo), Brazil(br), Chile(cl), Colombia(co), Ecuador(ec), FalklandIslands(fk), FrenchGuiana(gf), Guyana(gy), Paraguay(py), Peru(pe), SouthGeorgia(gs), Suriname(sr), Uruguay(uy), Venezuela(ve), UnitedArabEmirates(ae), Afghanistan(af), Bangladesh(bd), Bahrain(bh), Brunei(bn), Bhutan(bt), China(cn), HongKong(hk), Indonesia(id), Israel(il), India(in), Iraq(iq), Iran(ir), Jordan(jo), Japan(jp), Kyrgyzstan(kg), Cambodia(kh), SouthKorea(kr), Kuwait(kw), Laos(la), Lebanon(lb), SriLanka(lk), Mongolia(mn), Macao(mo), Maldives(mv), Myanmar(mm), Malaysia(my), NorthKorea(kp), Nepal(np), Oman(om), Philippines(ph), Pakistan(pk), Palestine(ps), Qatar(qa), SaudiArabia(sa), Singapore(sg), Syria(sy), Thailand(th), Tajikistan(tj), EastTimor(tl), Turkmenistan(tm), Taiwan(tw), Uzbekistan(uz), Vietnam(vn), Yemen(ye), Nigeria(ne), Ethiopia(et), Eritrea(er), Congo(cg), DemocraticCongo(cd), Tanzania(tz), SouthAfrica(za), Kenya(ke), Uganda(ug), SouthSudan(ss), Sudan(sd), Algeria(dz), Egypt(eg), Libya(ly), Madeira(ly), Morocco(ma), Angola(ao), Ghana(gh), Mozambique(mz), Madagascar(mg), Mayotte(yt), IvoryCoast(ci), Cameroon(cm), Niger(ne), BurkinaFaso(bf), Mali(ml), Malawi(mw), Zambia(zm), Chad(td), Somalia(so), Senegal(sn), Zimbabwe(zw), Guinea(gn), R\u00e9union(re), Rwanda(rw), Benin(bj), Burundi(bi), Tunisia(tn), Togo(tg), SierraLeone(sl), Congo(cd), CentralAfrican(cf), Liberia(lr), Mauritania(mr), Eritrea(er), Gambia(gm), Botswana(bw), Namibia(na), Gabon(ga), Lesotho(ls), GuineaBissau(gw), EquatorialGuinea(gq), Mauritius(mu), Mozambique(mz), Eswatini(sz), Djibouti(dj), Comoros(km), CapeVerde(cv), WesternSahara(eh), S\u00e3oTom\u00e9andPr\u00edncipe(st), Seychelles(sc), TristandaCunha(sh), Australia(au), Christmasisland(cx), CocosIslands(cc), ManIsle(im), Kiribati(ki), Nauru(nr), NewCaledonia(nc), Fiji(fj), Micronesia(fm), PapuanewGuinea(pg), Vanuatu(vu), SolomonIslands(sb), Guam(gu), MarshallIslands(mh), NorthernMariana(mp), FrenchPolynesia(pf), Samoa(ws), WallisandFutuna(wf), Tuvalu(tv), Americansamoa(as), Pitcairn(pn), Palau(pw), Jersey(je), Antarctica(aq), NorFolkIsland(nf), Cookisland(ck), NewZealand(nz), Niue(nu), Tokelau(tk), Tonga(to), BritishIndianOcean(io), FrenchSouthernandaAtarctic(tf), Guernsey(gg), HeardandMacDonaldsIslands(hm), UsMinorOutlyingIslands(um), count:262<\/code><\/pre>\n\n\n\n<p>Edit: lis\u00e4tty uusi satunnaisuuden l\u00e4hde &#8211;twist (ressu with twist). Siit\u00e4 haettavien bittien pit\u00e4isi olla otp kelpoisia. Eli jos ressu on one time pad kelpoinen, ja se s\u00e4ilyy otp kelpoisena kun siihen summataan toinen generaattori (t\u00e4ss\u00e4 pseudoressu), &#8211;twist:in tulos on otp kelpoinen.<\/p>\n\n\n\n<p>Edit: korjattu &#8220;bad for randomness&#8221; bugi ressu_genbytes():ss\u00e4.<\/p>\n\n\n\n<p>Edit: lis\u00e4tty test_bytes() funktio, johon voit kirjoittaa oman satunnaislukugeneraattorisi, ja ajaa sit\u00e4 newressun &#8211;test komentoriviparametrill\u00e4. <\/p>\n\n\n\n<p>Edit: lis\u00e4tty ressun satunnaisuutta k\u00e4ytt\u00e4v\u00e4 ohjelma newressusudoku, jolla voi etsi\u00e4 sudokuja.<\/p>\n\n\n\n<p>Edit: lis\u00e4tty satunnaisluvut heprean merkist\u00f6ll\u00e4 (hebrew, &#8211;heb)<\/p>\n\n\n\n<p>Edit: lis\u00e4tty &#8211;depth kytkin uuden copy-reversen testaamiseksi.<\/p>\n\n\n\n<p>Edit: lis\u00e4tty satunnaisluvut foinikialaisella merkist\u00f6ll\u00e4 (Phoenician, &#8211;pho).<\/p>\n\n\n\n<p>Esimm\u00e4iset funktiot sis\u00e4lt\u00e4v\u00e4t varsinaisen kellon luvun ja kellon esik\u00e4sittelyn. Esik\u00e4sittely on uusi ominaisuus, jossa kellojono jaetaan satunnaisesti 2-257 merkki\u00e4 sis\u00e4lt\u00e4viin &#8220;blokkeihin&#8221;, ja joka toinen blokki palautetaan sellaisenaan (copy) ja joka toinen palautetaan k\u00e4\u00e4nnetyss\u00e4 j\u00e4rjestyksess\u00e4 (reverse). T\u00e4ll\u00e4 tavalla sain kellojonon aiemman esik\u00e4sittelyn &#8220;symmetrisemm\u00e4ksi&#8221;, ja koska kellojonon k\u00e4sittelyss\u00e4 ei en\u00e4\u00e4 ole aiemman version ohituksia (skip) my\u00f6s kellojonon &#8220;tuhlaus&#8221; loppuu. T\u00e4m\u00e4n esik\u00e4sittelyn pit\u00e4isi tehd\u00e4 mahdottomaksi kellojonon arvaaminen.<\/p>\n\n\n\n<p>Kellojonon k\u00e4sittelyyn on my\u00f6s lis\u00e4tty uusi &#8211;fixedclock toiminto, jolla kellojonon ketjut ovat aina yht\u00e4 pitki\u00e4. T\u00e4ll\u00e4 voidaan ensinn\u00e4kin mietti\u00e4 muodostaako pelkk\u00e4 copy-reverse ilman kellojonon vaihtelua tarvittavasti satunnaisuutta sellaisenaan, ja toisaalta taas sen ymm\u00e4rt\u00e4minen, miten uusi copy-reverse vaikuttaa.<\/p>\n\n\n\n<p>Ensiksi alkuper\u00e4inen kellojonon luku.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char ressu_clockbyte2() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}<\/code><\/pre>\n\n\n\n<p>Sitten ns kiinte\u00e4mittaista kellojonoa tarjoava rutiini:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define FIXEDCLOCKCHAINLENGTH 80\nunsigned int fixedclockchainlength = FIXEDCLOCKCHAINLENGTH;\n\nstatic unsigned char ressu_fixedclockbyte2() \/* JariK 2022 *\/\n{\n  static unsigned int clockbyte = 0, counter = 0;\n\n  if(counter == 0) {\n    clockbyte++;\n    counter += fixedclockchainlength;\n  }\n  counter--;\n  return(clockbyte &amp; 0xff);\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 fixed\/normal valinnan tekev\u00e4 rutiini. Ensimm\u00e4isen kerran n\u00e4iss\u00e4 raporteissa osoite funktioon (pointer to function) tyyppinen muuttuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char (*clockfunc)()= &amp;ressu_clockbyte2; \/\/ normal\n\nvoid ressu_setclock(int clockmode)\n{\n  if(!clockmode)\n    clockfunc = &amp;ressu_clockbyte2; \/\/ normal\n  else\n    clockfunc = &amp;ressu_fixedclockbyte2; \/\/ fixed\n}<\/code><\/pre>\n\n\n\n<p>Seuraavana &#8220;mukamas&#8221; satunnaisia lukuja tekev\u00e4 rutiini. Tulos on kuitenkin satunnainen, koska sit\u00e4 k\u00e4ytet\u00e4\u00e4n indeksin\u00e4 satunnaislukupuskuriin. T\u00e4m\u00e4 funktio oli jo copy-skip versiossa, t\u00e4ss\u00e4 se on ulkoistettu koska sit\u00e4 k\u00e4ytet\u00e4\u00e4n kaksi kertaa, kerran copy:lle ja kerran reverse:lle.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned int ressu_nonrandom() \/\/ not really random\n{\n  static unsigned int rando = 0;\n\n  rando = rando +\n    clockbytes +\n    genbytes +\n    time(NULL) +\n    clock() +\n    get_useconds() +\n    ch * ch;\n\n  return(rando);\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 kellojonon esik\u00e4sittely joka kopioi tai k\u00e4\u00e4nt\u00e4\u00e4 seuraavan lohkon: (huomaa ch = (*clockfunc)() joka palauttaa joko tavallisen tai kiinte\u00e4nmittaisen kellojonon).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *ressuct; \/\/ ressu random buffer lookup\nunsigned int ressuct_bytes;\n\nstatic unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  static int reverse = 0; \/\/ 0 = copy, 1 = reverse, 28.10.2022 JariK\n  static unsigned char reversebytes&#91;256];\n  static unsigned int count = 0;\n\n  if(reverse) {\n    if(count == 0) {\n      count = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 1;\n      rndbits2 += 8;\n#ifdef DEBUG2A\n      fprintf(stdout,\"rev:  %03x  \", count);\n#endif\n      for(int c = 0; c &lt; count; c++) {\n\n\treversebytes&#91;c] = (*clockfunc)();\n\t\/\/reversebytes&#91;c] = ressu_clockbyte2();\n\n#ifdef DEBUG2A\n\tfprintf(stdout,\" %02x\", reversebytes&#91;c]);\n\tnewressu_output = 1;\n#endif\n      }\n#ifdef DEBUG2A\n      fprintf(stdout,\"\\n\");\n#endif\n    }\n    ch = reversebytes&#91;--count];\n#ifdef DEBUG2A\n    fprintf(stdout,\" ch:%02x\", ch);\n#endif\n    if(count == 0) {\n      reverse = 0;\n#ifdef DEBUG2A\n      fprintf(stdout,\"\\n\");\n#endif\n    }\n  } else {\n    if(count == 0) {\n      count = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 1;\n      rndbits2 += 8;\n#ifdef DEBUG2A\n      fprintf(stdout,\"copy: %03x  \", count);\n#endif\n    }\n\n    ch = (*clockfunc)();\n    \/\/ch = ressu_clockbyte2();\n\n#ifdef DEBUG2A\n    fprintf(stdout,\" ch:%02x\", ch);\n    newressu_output = 1;\n#endif\n\n    if(--count == 0) {\n      reverse = 1;\n#ifdef DEBUG2A\n      fprintf(stdout,\"\\n\");\n#endif\n    }\n  }\n#ifdef DEBUG2A\n  fflush(stdout);\n#endif\n  \n  return(ch);\n}\n<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 edellinen ilman #ifdef DEBUG2A rivej\u00e4: (debukilla voi muuten katsella miten copy reverse k\u00e4ytt\u00e4ytyy).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  static int reverse = 0; \/\/ 0 = copy, 1 = reverse, 28.10.2022 JariK\n  static unsigned char reversebytes&#91;256];\n  static unsigned int count = 0;\n\n  if(reverse) {\n    if(count == 0) {\n      count = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 1;\n      rndbits2 += 8;\n      for(int c = 0; c &lt; count; c++) {\n\treversebytes&#91;c] = (*clockfunc)();\n\t\/\/reversebytes&#91;c] = ressu_clockbyte2();\n      }\n    }\n    ch = reversebytes&#91;--count];\n    if(count == 0) {\n      reverse = 0;\n    }\n  } else {\n    if(count == 0) {\n      count = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 1;\n      rndbits2 += 8;\n    }\n    ch = (*clockfunc)();\n    \/\/ch = ressu_clockbyte2();\n    if(--count == 0) {\n      reverse = 1;\n    }\n  }\n  \n  return(ch);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa fixed moodissa tehtyj\u00e4 satunnaisbittej\u00e4 : (&#8211;stat optio tuo tulosteeseen my\u00f6s kaksi statistics rivi\u00e4. Huomaa ett\u00e4 pisin kellojono on tuo 80 merkki\u00e4, kaikki muut ketjut ovat satunnaisista kohdista katkaistuja saman mittaisia ketjuja)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --fixedclock --stat\nrandomsource: ressu, clockmode: 1, clockchainlength: 80, size: 5, lines: 10, linew: 13, pchars: 71, pwords: 13, tchars: 650, digitscount: 10, wordvalues: 100000, limit: 100000\nrounds:10 1:38 2:37 3:25 4:20 5:30 6:37 7:30 8:27 9:25 10:29 11:32 12:19 13:28 14:36 15:31 16:35 17:19 18:31 19:18 20:28 21:28 22:24 23:31 24:25 25:30 26:38 27:29 28:29 29:39 30:27 31:26 32:29 33:24 34:22 35:26 36:24 37:44 38:25 39:32 40:32 41:28 42:21 43:40 44:23 45:23 46:21 47:24 48:27 49:27 50:23 51:33 52:26 53:26 54:31 55:23 56:23 57:28 58:19 59:29 60:22 61:17 62:28 63:20 64:27 65:22 66:29 67:23 68:16 69:24 70:20 71:21 72:23 73:30 74:27 75:26 76:18 77:15 78:27 79:26 80:1041, chains:3156, sorted: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 35 36 37 38 39 40 44 1041, high1:1041, high2:44, lim1a:37, lim1b:38, lim1:37, lim2:38, div:1.027027, clockbytes:163760, rndbits1:1916, rndbits2:16488, rndbits3high:1041, rndbits3:2115, rndbits4highdigits:4, rndbits4:2115, rndbits5:3156, rndbits6high:1041, rndbits6:10576, rndbits7high:1041, rndbits7:21067\n00000 22294132938409767835685350193923839292365996595976935862826433282\n00001 48488719945788375230776214888393776008587235060334557977496406293\n00002 80431275143976461305838453114822706361730974050477594023459017094\n00003 93206417217628250656515986177836863340864892051316267057597113916\n00004 61731938638333708609330161928363100282423290987243662193954403192\n00005 94982923919430464067869481643568801481659685690996569554171263466\n00006 73313649799714726811829474731299233472648891876654506268759611113\n00007 71330815013503135793796350332802986281525959248136439352537631481\n00008 80520675067022116837313859689861210963143997805965619140693304090\n00009 27529324544421024520929292748015725933677643980607578142560612229<\/code><\/pre>\n\n\n\n<p>Sitten DEBUG2A tulostetta normal moodissa: (ch: on palautettava merkki, copy: sanan j\u00e4lkeen tulee merkkien lukum\u00e4\u00e4r\u00e4 ja kopioitava blokki, rev: sanan j\u00e4lkeen merkkien lukum\u00e4\u00e4r\u00e4, merkit alkuper\u00e4isess\u00e4 j\u00e4rjestyksess\u00e4 ja sitten k\u00e4\u00e4nnetyss\u00e4 j\u00e4rjestyksess\u00e4).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>copy: 015   ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21\nrev:  019   21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21\n ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21\ncopy: 016   ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21\nrev:  00a   21 21 21 21 21 21 21 22 22 22\n ch:22 ch:22 ch:22 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21 ch:21\ncopy: 010   ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22\nrev:  018   22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22\n ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22\ncopy: 014   ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22\nrev:  00f   22 22 22 22 22 22 22 22 22 22 22 22 22 22 22\n ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22 ch:22<\/code><\/pre>\n\n\n\n<p>Mielenkiintoista on, voiko teoreettisten satunnaismerkkien laskennan (rndbits1, rndbits3 jne) j\u00e4tt\u00e4\u00e4 kokonaan pois kun copy-reverse on toiminnassa, sit\u00e4 voi yritt\u00e4\u00e4 hahmottaa newressu &#8211;single komennolla.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --stat --single\nrandomsource: single, clockmode: 0, size: 5, lines: 10, linew: 13, pchars: 71, pwords: 13, tchars: 650, digitscount: 10, wordvalues: 100000, limit: 100000\nrounds:1 1:38 2:35 3:6 4:13 5:13 6:9 7:11 8:9 9:9 10:7 11:5 12:7 13:9 14:62 15:169 16:8 17:1 18:6 19:122 20:68, chains:607, clockbytes:8187, rndbits2:1128\n00000 32262283161809391678657136366555756828967803578676610526738617216\n00001 69511031437775242989469007588191015483302697394274894700778823040\n00002 76140983583748585072353786938410170011199037634650689281079597904\n00003 93729335401437288771146924781560699584385747294818636367091300176\n00004 05265892091793398109092431528679114647250196564188868255370175310\n00005 32662058346170613285279049952971968089134474619682155846073978431\n00006 37542509108789762598062162668902832635630435392168038872003862287\n00007 49867796710786537902924653466617634225652081735463098061052717754\n00008 40532647329764438978005136772857284492053527665773437979327537731\n00009 68916755542984513818470885899001010383458534877845952219318341042<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 fast versio, jossa oletetaan, ett\u00e4 copy-reversen 8 bitti\u00e4 blokki (rndbits2) on oikea satunnaisuuden m\u00e4\u00e4r\u00e4. T\u00e4ss\u00e4 ei siis testata noita muita teoreettisen satunnaisuuden kentti\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --stat --fast\nrandomsource: fast, clockmode: 0, size: 5, lines: 10, linew: 13, pchars: 71, pwords: 13, tchars: 650, digitscount: 10, wordvalues: 100000, limit: 100000\nrounds:3 1:18 2:19 3:19 4:13 5:11 6:23 7:16 8:18 9:22 10:10 11:18 12:14 13:12 14:11 15:14 16:13 17:14 18:16 19:11 20:16 21:27 22:301 23:99 24:16 25:10 26:13 27:10 28:11 29:7 30:9 31:5 32:72 33:181 34:16 35:11 36:5 37:6 40:3 41:3, chains:1113, sorted: 3 5 6 7 9 10 11 12 13 14 16 18 19 22 23 27 72 99 181 301, clockbytes:24556, rndbits2:1736\n00000 68784755242708765294394273037319039572739737000724542275166407714\n00001 06972592691192404285861495591371050958299735095969537656132751909\n00002 67574262177835663992021063370107991617814973885686637190673088094\n00003 23737673519966062499715155344625118562351368088477401742394627022\n00004 03263216076372320938776167737005047546185162611650283796001101369\n00005 51407508376549070991359975767652992476157609203411915065410641295\n00006 12655893530487345584253510097815082335938955217832759445595250214\n00007 24937072376561882973994015071952414930388304299234767961731321584\n00008 05580710011089642452809116400909876953773223311014848926770989925\n00009 80053600376650552642904242376127515525297384309817394907301522152<\/code><\/pre>\n\n\n\n<p>Joka tapauksessa perusversio: teoreettisten satunnaismerkkien laskemisineen ja copy-reverse:n kanssa on mielest\u00e4ni versio korotuksen arvoinen. (Teilt\u00e4 pit\u00e4isi kysy\u00e4 onko se valmis&#8230;) Suorittelen kuitenkin, kuten aina, sen k\u00e4ytt\u00e4mist\u00e4 muiden generaattorien kanssa, ja viimeinen tietysti omassa ohjelmassa. N\u00e4ist\u00e4 omistani &#8211;pseudoressu tulee mieleen, siit\u00e4 jatkossa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu\n00000 37623172794213955845654028970142043156650464162378618125059418215\n00001 44770808876162322824064917059041951056355916863064355533513084242\n00002 75485713017878047234034253933802355371072968018532606905129869680\n00003 96551784242102846132000149967407451652050029473735516535627149942\n00004 91453561873005997442161145845169261020298914882602023854201229781\n00005 72203425783242175112239728887442139124665422626613641888668562931\n00006 01828527840750137347400562529323569375142224887300242484404778626\n00007 34038142372693997824692927661290471630937124920642848309126302336\n00008 71422612084979552308234145197900652207559401420147297100214334402\n00009 64387847336829223605559797922477255813426710680768085663528529936<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 ressun &#8220;ydin&#8221; ja liit\u00e4nn\u00e4istoiminnot. Uudelleen nimetty p\u00e4\u00e4funktio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define RR8(byte,bits) ( ((byte) &gt;&gt; (bits)) | ((byte) &lt;&lt; (8 - (bits))) )\n#define RL8(byte,bits) ( ((byte) &gt;&gt; (8 - (bits))) | ((byte) &lt;&lt; (bits)) )\n\n#define aDEBUG5 2\n\nvoid ressu_genbytes_single_do(int size, unsigned char *buffer)\n{\n  int c, d;\n  unsigned char e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  \/\/ressuct = buffer;  \/\/ ressu random buffer lookup\n  \/\/ressuct_bytes = size;\n  \n  for(c = 0; c &lt; 8; c++) {\n    for(d = 0; d &lt; size; d++) {\n      e = buffer&#91;d];\n      e = RL8(e, 1); \/\/ rotate byte left 1 bits\n      \/\/e = RL8(e, 3); \/\/ rotate byte left 3 bits\n      \/\/e = RR8(e, 1); \/\/ rotate byte right 1 bits\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#ifdef DEBUG5\n    if(newressu_output)\n      fprintf(stdout, \"\\n\");\n    ressu_dump(\"single 1\", 32, buffer, 32);\n#endif\n    for(d = 0; d &lt; size; d++) {\n      f = (f + buffer&#91;d] + 2) % size; \/\/ +2 JariK 2022\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n#ifdef DEBUG5\n    if(newressu_output)\n      fprintf(stdout,\"\\n\");\n    ressu_dump(\"single 2\", 32, buffer, 32);\n#endif\n  }\n}<\/code><\/pre>\n\n\n\n<p>Ja uusi versio ressu_genbytes_single() funktiosta, johon on lis\u00e4ttu &#8211;stat rivit,  ja uusi genbytes_single_do() -kutsu:<\/p>\n\n\n\n<p>Nuo ensimm\u00e4iset ressu_ct ja _bytes kertovat paikan josta uusi copy-reverse hakee blokin pituuden. Pituudet haetaan aina k\u00e4sittelyn alla olevasta satunnaisbittipuskurista.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes_single(int size, unsigned char *buffer)\n{\n  ressuct = buffer;  \/\/ ressu random buffer lookup\n  ressuct_bytes = size;\n  \n  rndbits2 = 0;\n  clockbytes = 0;\n\n  ressu_genbytes_single_do(size, buffer);\n\n  \/\/\n  \/\/  display statistics\n  \/\/\n  if(stats) {\n\n    if(newressu_output == 1)\n      fprintf(stdout, \"\\n\");\n    newressu_output = 0;\n\n    fprintf(stderr, \"rounds:1\");\n\n    long chains = 0;\n    \n    for(int e = 0; e &lt; 1024; e++) {\n      if(periods&#91;e] &gt; 0) {\n\tfprintf(stderr, \" %d:%lu\", e, periods&#91;e]);\n\tchains += periods&#91;e];\n      }\n    }\n    \n    fprintf(stderr, \", chains:%ld\", chains);\n    fprintf(stderr, \", clockbytes:%ld\", clockbytes);\n    fprintf(stderr, \", rndbits2:%d\", rndbits2);\n    fprintf(stderr, \"\\n\");\n    fflush(stderr);\n  }\n}<\/code><\/pre>\n\n\n\n<p>Sitten ressu ressu_genbytes(): jossa lis\u00e4tyt ressuct ja _bytes muuttujat kellojonon pituuden hakemista varten ja muutettu kutsu ressu_genbytes_single_do &#8220;ydint\u00e4&#8221; varten.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG7 2\n#define aDEBUG2 2\n\nvoid ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c, d, e, f;\n  static unsigned char ressut&#91;RESSUT_BYTES];\n  static int ressut_first = 1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  unsigned long prevperiods&#91;1024];\n\n#ifdef DEBUG2\n  static unsigned char counts&#91;RESSUT_BYTES];\n#endif\n  \n  ressuct = ressut;  \/\/ ressu random buffer lookup\n  ressuct_bytes = ressut_bytes; \/\/ table used in ressu_genbytes_single_do\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\n#ifdef DEBUG2\n      for(d = 0; d &lt; size; d++)\n\tcounts&#91;d] = 0;\n#endif\n      \n      rndbits1 = 0;\n      rndbits2 = 0;\n      rndbits3 = 0;\n      rndbits4 = 0;\n      rndbits5 = 0;\n      rndbits6 = 0;\n      rndbits7 = 0;\n\n      int lim, lim1 = 0, lim2 = 0;\n      int lim1a, lim1b;\n      int high1, high2;\n\n      int rndbits3high;\n      int rndbits4highdigits;\n      int rndbits6high;\n      int rndbits6pos;\n      int rndbits7high;\n      \n      for(d = 0;\n\t  rndbits1 &lt; ressu_bits1_needed ||\n\t  rndbits2 &lt; ressu_bits2_needed ||\n\t  rndbits3 &lt; ressu_bits3_needed ||\n\t  rndbits4 &lt; ressu_bits4_needed ||\n\t  rndbits5 &lt; ressu_bits5_needed ||\n\t  rndbits6 &lt; ressu_bits6_needed ||\n\t  rndbits7 &lt; ressu_bits7_needed ||\n\t  d &lt; RESSU_MIN_ROUNDS ||\n\t  clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n#define aDEBUG6 2\n\t\n\t\/\/\n\t\/\/  calculate rndbits1\n\t\/\/\n\t\n\t\/\/ save previous round\n\n        for(e = 0; e &lt; 1024; e++) {\n\t  prevperiods&#91;e] = periods&#91;e];\n\t}\n\n\tressu_genbytes_single_do(ressut_bytes, ressut);\n\n\t\/\/ find new lim1\n\t\n\tlim = lim1;\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(prevperiods&#91;e] &gt; 0 &amp;&amp; prevperiods&#91;e] == lim) {\n\t    if(f == -1 || (periods&#91;e]&gt;0 &amp;&amp; f&lt;periods&#91;e])) {\n\t      f  = periods&#91;e];\n\t    }\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim = f;\n\n\tlim1a = lim;\n\t\n\t\/\/ find highest amount of chains\n\t\n\thigh1 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(high1 == -1 || high1 &lt; periods&#91;e]) {\n\t    high1 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and second highest\n\t\n\thigh2 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (high2 == -1 &amp;&amp; periods&#91;e] &lt; high1) ||\n\t      (high2 &lt; periods&#91;e] &amp;&amp; periods&#91;e] &lt; high1) ) {\n\t    high2 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and average\n\n\tint psum = 0;\n\tint pcnt = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0) {\n\t    psum += periods&#91;e];\n\t    pcnt++;\n\t  }\n\t}\n\n\tlim1b = (int)((double)psum \/ pcnt);\n\t\n\t\/\/ find next smaller than average\n\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (f == -1 &amp;&amp; periods&#91;e] &lt; lim1b) ||\n\t      (f &lt; periods&#91;e] &amp;&amp; periods&#91;e] &lt; lim1b) ) {\n\t    f = periods&#91;e];\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim1b = f;\n\n\tif(lim == 0 || lim &gt; lim1b)\n\t  lim = lim1b;\n\n\t\/\/ if lim greater that second highest,\n\t\/\/ set to second highest\n\n\tif(lim &gt; high2) {\n\t  lim = high2;\n\t}\n\t\t\n\tlim1 = lim;\n\n\t\/\/ find next greater than lim\n\t\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; lim &amp;&amp;\n\t     (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\n\t\/\/ calculate rndbits1\n\n#define aDEBUG6 2\n\t\n\trndbits1 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0 &amp;&amp; periods&#91;e] &lt; lim) {\n\t    rndbits1 += periods&#91;e];\n\t  }\n\t}\n\t\n\t\/\/\n\t\/\/  calculate rndbits3\n\t\/\/\n\n#define aDEBUG8 2\n\t\n\trndbits3high = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits3high &lt; periods&#91;e])\n\t    rndbits3high = periods&#91;e];\n\t}\n\n\trndbits3 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits3high &gt; periods&#91;e]) {\n\t    rndbits3 += periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits4\n\t\/\/\n\n#define aDEBUG9 2\n\t\n\trndbits4highdigits = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &lt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4highdigits = (int)log10((double)periods&#91;e]) + 1;\n\t  }\n\t}\n\n\trndbits4 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &gt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4 += periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits5\n\t\/\/\n\n#define aDEBUG10 2\n\t\n\trndbits5 = 0;\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  rndbits5 += periods&#91;e];\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits6\n\t\/\/\n\n#define aDEBUG11 2\n\t\n\trndbits6high = 0;\n\trndbits6pos = 0;\n\trndbits6 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits6high &lt; periods&#91;e]) {\n\t    rndbits6high = periods&#91;e];\n\t    rndbits6pos = e;\n\t  }\n\t}\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits6high &gt; periods&#91;e] &amp;&amp; periodsl&#91;e] &gt; 0) {\n\t    if(rndbits6pos &gt; e)\n\t      rndbits6 += log2((double)rndbits6pos - e) * periods&#91;e];\n\t    else\n\t      rndbits6 += log2((double)e - rndbits6pos) * periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits7\n\t\/\/\n\n#define aDEBUG12 2\n\t\n\trndbits7high = 0;\n\trndbits7 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits7high &lt; periods&#91;e])\n\t    rndbits7high = periods&#91;e];\n\t}\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits7high &gt; periods&#91;e] &amp;&amp; periods&#91;e] &gt; 0) {\n\t    rndbits7 += log2((double)rndbits7high - periods&#91;e]) * periods&#91;e];\n\t  }\n\t}\n      } \/\/ for(d=0;\n      \n      \/\/\n      \/\/ debug display for rndbits1\n      \/\/\n\n#ifdef DEBUG6\n\t\n      rndbits1 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(periods&#91;e] &gt; 0 &amp;&amp; periods&#91;e] &lt; lim) {\n\t  rndbits1 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits1+prev:%d\", rndbits1);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits3\n      \/\/\n\n#ifdef DEBUG8\n\t\n      rndbits3 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits3high &gt; periods&#91;e] &amp;&amp;\n\t   periods&#91;e] &gt; 0) {\n\t  rndbits3 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits3+prev:%d\", rndbits3);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits4\n      \/\/\n\n#ifdef DEBUG9\n      \n      rndbits4 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits4highdigits &gt; (int)log10((double)periods&#91;e]) + 1 &amp;&amp;\n\t   periods&#91;e] &gt; 0) {\n\t  rndbits4 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits4+prev:%d\", rndbits4);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits5\n      \/\/\n\n#ifdef DEBUG10\n\n      rndbits5 = 0;\n\n      for(e = 0; e &lt; 1024; e++) {\n\tif(periods&#91;e] &gt; 0) {\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  rndbits5 += periods&#91;e];\n\t  fprintf(stderr,\", rndbits5+prev:%d\", rndbits5);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug diplay for rndbits6\n      \/\/\n\n#ifdef DEBUG11\n\t\n      rndbits6 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits6high &gt; periods&#91;e] &amp;&amp;\n\t   periods&#91;e] &gt; 0) {\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%lu\", periods&#91;e]);\n\n\t  double l2;\n\n\t  if(rndbits6pos &gt; e) {\n\t    fprintf(stderr,\", pos-e:%d\", rndbits6pos - e);\n\t    l2 = log2((double)rndbits6pos - e);\n\t  } else {\n\t    fprintf(stderr,\", e-pos:%d\", e - rndbits6pos);\n\t    l2 = log2((double)e - rndbits6pos);\n\t  }\n\t  fprintf(stderr,\", log2(prev):%f\", l2);\n\t  fprintf(stderr,\", periods*prev:%ld\", (long int) ((double)periods&#91;e] * l2));\n\t  rndbits6 += l2 * periods&#91;e];\n\t  fprintf(stderr,\", rndbits6+prev:%d\", rndbits6);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug diplay for rndbits7\n      \/\/\n\n#ifdef DEBUG12\n\t\n      rndbits7 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits7high &gt; periods&#91;e] &amp;&amp;\n\t   periods&#91;e] &gt; 0) {\n\t  rndbits7 += log2((double)rndbits7high - periods&#91;e]) * periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", high-prev:%ld\", rndbits7high-periods&#91;e]);\n\t  double l2=log2((double)rndbits7high-periods&#91;e]);\n\t  fprintf(stderr,\", log2(prev):%f\", l2);\n\t  fprintf(stderr,\", periods*prev:%ld\", (long int) ((double)periods&#91;e] * l2));\n\t  fprintf(stderr,\", rndbits7+prev:%d\", rndbits7);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      if(stats) {\n\n\tif(newressu_output == 1)\n\t  fprintf(stderr,\"\\n\");\n\tnewressu_output = 0;\n\t\n\t\/\/\n\t\/\/  display statistics\n\t\/\/\n\tfprintf(stderr, \"rounds:%d\", d);\n\n\tlong chains = 0;\n    \n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0) {\n\t    fprintf(stderr, \" %d:%lu\", e, periods&#91;e]);\n\t    chains += periods&#91;e];\n\t  }\n\t}\n\n\tfprintf(stderr, \", chains:%ld\", chains);\n\t\n#ifdef DEBUG_SORTED\n\t\n\tfprintf(stderr, \", sorted:\");\n\tint g = 0;\n\tfor(;;) {\n\t  f = -1;\n\t  for(e = 0; e &lt; 1024; e++) {\n\t    if( (f == -1 &amp;&amp; periods&#91;e] &gt; g) ||\n\t\t(periods&#91;e] &gt; g &amp;&amp; f &gt; periods&#91;e]) )\n\t      f = periods&#91;e];\n\t  }\n\t  if(f == -1)\n\t    break;\n\n\t  g = f;\n\t  fprintf(stderr,\" %d\", g);\n\t}\n\n#endif\n\tfprintf(stderr, \", high1:%d\", high1);\n\tfprintf(stderr, \", high2:%d\", high2);\n\tfprintf(stderr, \", lim1a:%d\", lim1a);\n\tfprintf(stderr, \", lim1b:%d\", lim1b);\n\tfprintf(stderr, \", lim1:%d\", lim1);\n\tfprintf(stderr, \", lim2:%d\", lim2);\n\tfprintf(stderr, \", div:%f\", (double)lim2 \/ lim1);\n\tfprintf(stderr, \", clockbytes:%ld\", clockbytes);\n\tfprintf(stderr, \", rndbits1:%d\", rndbits1);\n\tfprintf(stderr, \", rndbits2:%d\", rndbits2);\n\tfprintf(stderr, \", rndbits3high:%d\", rndbits3high);\n\tfprintf(stderr, \", rndbits3:%d\", rndbits3);\n\tfprintf(stderr, \", rndbits4highdigits:%d\", rndbits4highdigits);\n\tfprintf(stderr, \", rndbits4:%d\", rndbits4);\n\tfprintf(stderr, \", rndbits5:%d\", rndbits5);\n\tfprintf(stderr, \", rndbits6high:%d\", rndbits6high);\n\tfprintf(stderr, \", rndbits6:%d\", rndbits6);\n\tfprintf(stderr, \", rndbits7high:%d\", rndbits7high);\n\tfprintf(stderr, \", rndbits7:%d\", rndbits7);\n\tfprintf(stderr, \"\\n\");\n\tfflush(stderr);\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  if(verbose) {\n    fprintf(stdout,\"ressu \");\n    for(c = 0; c &lt; size; c++) {\n      if(c &gt; 0 &amp;&amp; c % 32 == 0)\n\tfprintf(stdout,\" \");\n      fprintf(stdout,\"%02x\", buffer&#91;c]);\n      newressu_output = 1;\n    }\n    fprintf(stdout,\"\\n\");\n  }\n  \n#ifdef DEBUG7\n\n  ressu_dump(\"genbytes\", size, buffer, 32);\n\n#endif\n  \n  genbytes += size;\n}<\/code><\/pre>\n\n\n\n<p>Mielest\u00e4ni ressu (.\/newressu &#8211;ressu tai .\/newressu) on kelvollista jopa one time pad materiaaliksi (jokainen bitti irtonainen, ei ole laskennallista yhteytt\u00e4 muihin bitteihin paitsi tilastollinen todenn\u00e4k\u00f6isyys), ja jos noin olisi voisimme tehd\u00e4 nopeamman satunnaisgeneraattorin k\u00e4ytt\u00e4m\u00e4ll\u00e4 ressua satunnaisbittien l\u00e4hteen\u00e4 ja tehd\u00e4 uusia satunnaisbittej\u00e4 tiivistefunktiolla (t\u00e4ss\u00e4 sha256) (vertaa fort). T\u00e4ss\u00e4 generattoriehdokas: (ehdokas ei tietenk\u00e4\u00e4n ole one time pad materiaalia sha256 funktion vuoksi).<\/p>\n\n\n\n<p>Edit: Miksi sitten ressun bitit ovat riippumattomia. Helpoimmin p\u00e4\u00e4ttelyni j\u00e4ljille p\u00e4\u00e4see, jos kuvittelee ett\u00e4 kellomerkit on and:atty ykk\u00f6sell\u00e4. T\u00e4ll\u00f6in vain alin bitti kellojonosta j\u00e4\u00e4 j\u00e4ljelle. Kun and:atyll\u00e4 kellojonolla xor:ataan puskuri vain sen alin bitti muuttuu. Shift:iss\u00e4 alin bitti siirret\u00e4\u00e4n talteen kakkosbittiin ja kakkosbitti kolmosbittiin jne. Merkkien paikkaa muutetaan satunnaisesti ja aloitetaan alusta. Merkkien paikkojen satunnainen muuttaminen poistaa yhteyden yksitt\u00e4isten &#8220;samalla rivill\u00e4&#8221; olevien bittien v\u00e4lill\u00e4. Se ett\u00e4 yhden merkin eri bitit otetaan eri kohdasta kellojonosta ja vaihdetusta puskurinpaikasta varmistaa ett\u00e4 merkin biteille ei muodostu yhteytt\u00e4. (Huomaa ett\u00e4 my\u00f6s merkin paikka puskurissa vaikuttaa siihen mik\u00e4 merkki kellojonosta otetaan.) Jos t\u00e4h\u00e4n lis\u00e4t\u00e4\u00e4n muut bitit (ei tehd\u00e4 and:i\u00e4 ykk\u00f6sell\u00e4) muut bitit vain sekoittavat lis\u00e4\u00e4, yhteytt\u00e4 ei uudestaan synny.<\/p>\n\n\n\n<p>Edit: toisaalta, jos pseudoressun tulosjono summataan (xor) ressun tulosjonon kanssa yhteinen tulos on mielest\u00e4ni taas one time pad kelpoinen. Siis ressun tuloste on one time pad materiaalia, vaikka siihen summataan mit\u00e4, summaamisen j\u00e4lkeen se on edelleen one time pad materiaalia.<\/p>\n\n\n\n<p>Edit: seuraavassa esimerkki, jossa on listattuna yhdell\u00e4 and:\u00e4tyt puskurien alut: (ensimm\u00e4isell\u00e4 rivill\u00e4 vain nollabitti, eli arvot 0 ja 1. Seuraavalla rivill\u00e4 lis\u00e4tty ykk\u00f6sbitti eli arvo 2 (t\u00e4ll\u00f6in arvot ovat 0 1 2 ja 3). Seuraavalla kakkosbitti (4) eli arvot 0, 1, 2, 3, 4, 5, 6 ja 7. Rivej\u00e4 on t\u00e4ss\u00e4 8 kappaletta eli oma rivi jokaiselle uudelle bitille, viimeisen bitin arvo on 80 eli 128d. Seuraavan listan joissa on single 1 rivill\u00e4 single_do()-funktion shift ja xor ja single 2 rivill\u00e4 swap saat DEBUG5:lla. Lista on heksana ett\u00e4 voidaan tarkistaa ett\u00e4 viimeinen rivi on todella varsinaisella satunnaislukulistalla rivi 1. Huomaa ensimm\u00e4isen rivin swap:it. Kun swappailemme merkkej\u00e4 joissa on vain ykk\u00f6st\u00e4 ja nollaa, ilmeni ett\u00e4 niiss\u00e4 molemmissa on ep\u00e4symmetriaa verrattuna muihin merkkeihin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -x --fixedclock5| more\nsingle 1   01 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 01 01\nsingle 2   01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 01 01 01\n\nsingle 1   02 03 02 02 00 00 01 01 01 03 03 02 02 02 00 00 01 01 01 03 02 03 02 02 00 01 00 01 01 03 03 02\nsingle 2   02 02 01 00 00 01 01 00 01 03 01 01 00 02 01 02 02 01 03 00 00 01 03 03 02 03 00 02 00 02 01 02\nsingle 1   04 05 02 01 01 03 03 00 02 06 02 03 00 05 03 05 05 02 06 00 00 02 07 07 05 07 01 04 00 04 02 05\nsingle 2   07 07 01 06 06 03 05 04 05 03 03 06 00 06 02 02 03 02 06 06 03 00 07 00 02 04 02 00 05 05 04 04\nsingle 1   0f 0f 03 0c 0c 06 0a 08 0a 07 07 0d 01 0d 04 04 06 04 0d 0d 07 01 0f 00 04 08 04 00 0b 0a 08 09\nsingle 2   0b 0f 09 01 01 0b 04 03 05 09 09 08 0d 07 09 05 0a 09 04 0b 04 0f 03 04 0b 04 08 09 08 06 02 0f\nsingle 1   16 1e 12 02 02 17 09 07 0b 13 12 10 1a 0e 12 0b 15 13 09 16 08 1e 06 08 17 09 11 13 11 0c 04 1e\nsingle 2   0f 1f 00 0e 02 15 12 15 09 16 19 16 10 0f 07 19 13 0a 16 1e 05 1b 01 15 08 08 19 0f 1a 0a 16 0a\nsingle 1   1f 3f 01 1d 05 2a 24 2a 12 2c 33 2d 21 1f 0f 32 26 14 2c 3c 0b 37 03 2b 11 10 32 1e 34 14 2d 15\nsingle 2   17 01 28 33 16 19 2b 1f 1f 15 28 2b 35 0f 37 16 32 18 0d 28 27 1f 11 11 3e 0a 3f 10 3b 26 0a 30\nsingle 1   2f 03 50 66 2c 32 56 3f 3f 2b 51 57 6a 1e 6e 2c 64 31 1b 51 4f 3f 22 22 7c 14 7e 21 77 4d 15 61\nsingle 2   56 55 2b 3b 3d 70 22 52 79 6d 52 57 3e 29 24 1e 50 5c 36 13 2a 5b 00 54 43 0f 18 5e 13 5d 21 70\nsingle 1   ad ab 57 76 7a e0 44 a4 f3 db a5 af 7d 52 48 3c a0 b8 6d 27 55 b7 01 a8 86 1e 30 bc 27 bb 43 e1\nsingle 2   41 b1 01 14 dc a8 a2 36 48 a8 6a 97 85 13 62 3f 0b e0 b5 34 8d b9 c4 fa 65 bc 8c 93 b8 f9 f2 ef\n00000 41b10114dca8a23648a86a978513623f0be0b5348db9c4fa65bc8c93b8f9f2ef\n00001 119f2a30b1a5b7737d92f5ca7d55b2991bca8da85db795278876a0cc66cd7fee\n00002 40fe7e3eb56ee10680053fb69f00aa9e05b470490270875180bf545609d55db4\n00003 af82f8756838045d6d8b8bf2ada39b43456690bd7ca56cba3fa592ec660680a2\n00004 6f4370a240850ad1951fe555c1ef377b0b0fa20af3b1cd5381ac4a2916764eb2\n00005 5b59d45d9d19280b9115405c92a25a75cd4c53b051d5df45a0cd4b39163c5060\n00006 f4524aad74b97cab5bb6b6ae4baff0b609562aab71ddbd10b9473fb4f0be6940\n00007 587979249184244f17740e5a9e4a5047fd46c94b1721fad3ff964363a313b8b3\n00008 49724491c0ab1b9933c3a2f83caed2c97ea5482d5f0e5dfc775effde59a40bd4\n00009 2a558f2f09776189a4b812fa741b423172ad619853a5eddbc21674a1564c5701\n<\/code><\/pre>\n\n\n\n<p>Nolla toimi seuraavalla tavalla: swapiss\u00e4h\u00e4n f muuttujaan eli swapin kohteeseen lis\u00e4t\u00e4\u00e4n merkki swapin puskurin d:n kohdasta. Jos siis puskuri d:n sis\u00e4lt\u00f6 (bufferd) on nolla, f ei kasva, ja koko nollia sis\u00e4lt\u00e4v\u00e4 ketju j\u00e4\u00e4 &#8220;ripottelematta&#8221; puskuriin. Seuraavassa d k\u00e4y l\u00e4pi koko puskurin, f ei muutu mihink\u00e4\u00e4n, ja n\u00e4in koko nollaketju j\u00e4\u00e4 samanlaiseksi. Kun nollaketju loppuu swap:pi palaa takaisin normaaliin toimintaan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ressu 1    00 00 00 00 00 01 01 01 01 01 00 00 00 00 01 00 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00\nd:0, f:0, bufferd:0, bufferf:0\nd:1, f:0, bufferd:0, bufferf:0\nd:2, f:0, bufferd:0, bufferf:0\nd:3, f:0, bufferd:0, bufferf:0\nd:4, f:0, bufferd:0, bufferf:0\nd:5, f:0, bufferd:1, bufferf:0\nd:6, f:1, bufferd:1, bufferf:1\nd:7, f:2, bufferd:1, bufferf:1\nd:8, f:3, bufferd:1, bufferf:1\nd:9, f:4, bufferd:1, bufferf:1\nd:10, f:5, bufferd:0, bufferf:1\nd:11, f:5, bufferd:0, bufferf:0\nd:12, f:5, bufferd:0, bufferf:0<\/code><\/pre>\n\n\n\n<p>Ykk\u00f6sell\u00e4 ongelma oli seuraava: d kulkee taas puskurin alusta puskurin loppuun ja f:\u00e4\u00e4 kasvatetaan d:n sis\u00e4ll\u00f6ll\u00e4 (bufferd), siis f:\u00e4\u00e4 kasvatetaan yhdell\u00e4, t\u00e4ll\u00f6in laitetaan ykk\u00f6nen seuraavaan f:\u00e4\u00e4n, joka on tietenkin seuraava d:n sis\u00e4lt\u00f6. N\u00e4in f kasvaa joka kierroksella yhdell\u00e4 kunnes ykk\u00f6nen on siirretty puskurin viimeiseen merkkiin. Ykk\u00f6sversio ei siis palaa normaaliksi ykk\u00f6sten j\u00e4lkeen vaan jatkuu puskurin loppuun.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ressu 1    01 01 01 01 01 00 00 00 00 00 01 01 01 01 00 01 00 00 00 01 00 01 01 01 01 00 00 00 00 00 01 01\nd:0, f:0, bufferd:1, bufferf:1\nd:1, f:1, bufferd:1, bufferf:1\nd:2, f:2, bufferd:1, bufferf:1\nd:3, f:3, bufferd:1, bufferf:1\nd:4, f:4, bufferd:1, bufferf:1\nd:5, f:5, bufferd:1, bufferf:1\nd:6, f:6, bufferd:1, bufferf:1\nd:7, f:7, bufferd:1, bufferf:1\nd:8, f:8, bufferd:1, bufferf:1\nd:9, f:9, bufferd:1, bufferf:1\nd:10, f:10, bufferd:1, bufferf:1\nd:11, f:11, bufferd:1, bufferf:1\nd:12, f:12, bufferd:1, bufferf:1\nd:13, f:13, bufferd:1, bufferf:1<\/code><\/pre>\n\n\n\n<p>Korjaus on tietenkin ohittaa n\u00e4m\u00e4 tapaukset eli kasvattaa f:\u00e4\u00e4 d:n sis\u00e4ll\u00f6n lis\u00e4ksi kakkosella. (d muuttujaa ei voi muuttaa, varsinaista sw\u00e4ppi\u00e4 ei voi muuttaa, datan perusteella ei voi tehd\u00e4 logiikkaa (esim if data = &#8220;1&#8221;), joten ainoa vaihtoehto on muuttaa f:\u00e4\u00e4) Seuraavassa uusi swap:pi osuus:<\/p>\n\n\n\n<p>Ongelma ennen 0 ja 1 muutostakaan ei ollut tilastollisesti kovin yleinen. Suurin osa korjautui sill\u00e4 ett\u00e4 seuraavalla xor:lla nuo nollabitit ja ykk\u00f6sbitit muuttuvat toisiksi ja taas swappaytyv\u00e4t normaalisti. Periaatteessa puskurin viimeinen merkki oli hieman useammin ykk\u00f6nen, joten siit\u00e4 olisi voinut tehd\u00e4 tunnistuksen k\u00e4ytetyst\u00e4  ressusta. +2 muutoksen j\u00e4lkeen tunnistus ei tietenk\u00e4\u00e4n onnistu, nyt kaikki dataarvot toimivat uudessa versiossa symmetrisesti. Asiaa on tietysti tutkittava, ja osin uudelleen koska &#8220;syd\u00e4n&#8221; (ressu_genbytes_single_do()) on muuttunut.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG5A 2\n#define aDEBUG5B 2\n#define aDEBUG5C 2\n#define aLOWCLOCKBITONLY 2 \/\/ off by default \/\/\n\nvoid ressu_genbytes_single_do(int size, unsigned char *buffer) \/\/ JariK 2013\n...\n    for(d = 0; d &lt; size; d++) {\n#ifdef DEBUG5B\n      fprintf(stdout,\"d:%d\", d);\n      fprintf(stdout,\", f:%d\", f);\n      fprintf(stdout,\", bufferd:%d\", buffer&#91;d]);\n      fprintf(stdout,\", bufferf:%d\", buffer&#91;f]);\n      fprintf(stdout,\"\\n\");\n#endif\n      f = (f + buffer&#91;d] + 2) % size; \/\/ +2 JariK 2022\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n...\n}<\/code><\/pre>\n\n\n\n<p>F:\u00e4n kasvattaminen yhdell\u00e4 ei riit\u00e4, sill\u00e4 sitten nolla toimii kuten yksi \u00e4sken eli kulkee kaikkien puskuripaikkojen l\u00e4pi puskurin loppuun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ressu 1    00 00 00 00 00 01 01 01 01 01 00 00 00 00 01 00 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00\nd:0, f:0, bufferd:0, bufferf:0\nd:1, f:1, bufferd:0, bufferf:0\nd:2, f:2, bufferd:0, bufferf:0\nd:3, f:3, bufferd:0, bufferf:0\nd:4, f:4, bufferd:0, bufferf:0\nd:5, f:5, bufferd:0, bufferf:0\nd:6, f:6, bufferd:0, bufferf:0\nd:7, f:7, bufferd:0, bufferf:0\nd:8, f:8, bufferd:0, bufferf:0\nd:9, f:9, bufferd:0, bufferf:0\nd:10, f:10, bufferd:0, bufferf:0\nd:11, f:11, bufferd:0, bufferf:0\nd:12, f:12, bufferd:0, bufferf:0\nd:13, f:13, bufferd:0, bufferf:0<\/code><\/pre>\n\n\n\n<p>Lista, jossa aiempi ensimm\u00e4inen swappirivi oli melkein muuttumaton, t\u00e4ss\u00e4 se n\u00e4ytt\u00e4\u00e4 jo kohtuulliselta (+2 version): T\u00e4ss\u00e4 on otettava huomioon ett\u00e4 t\u00e4m\u00e4 on ensimm\u00e4inen swappi puskurille joka sis\u00e4lt\u00e4\u00e4 pelk\u00e4st\u00e4\u00e4n ykk\u00f6si\u00e4 ja nollia pitkin\u00e4 jonoina. Seuraavat swap:it lis\u00e4\u00e4v\u00e4t tietysti satunnaisuutta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -x\nressu 1    00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00\nressu 2    00 01 01 01 01 00 01 00 01 00 00 01 01 00 01 01 00 00 01 00 01 01 01 01 00 00 00 01 01 01 00 01\nressu 1    01 02 02 02 02 00 02 00 02 01 01 03 03 01 03 03 01 01 03 01 03 03 03 03 01 01 01 03 03 03 01 03\nressu 2    02 00 01 02 03 02 02 01 01 03 01 03 03 00 01 03 01 03 00 01 01 01 01 03 01 03 01 03 01 00 01 02\nressu 1    04 00 02 04 06 05 05 03 03 07 03 07 07 01 03 07 03 07 01 03 03 03 03 07 03 07 03 07 03 01 03 05\nressu 2    00 02 00 06 03 03 03 00 06 00 06 02 01 01 04 02 02 05 01 00 04 03 04 02 01 07 06 05 01 06 02 06\nressu 1    00 04 00 0c 06 06 06 00 0c 00 0c 04 02 02 08 04 04 0b 03 01 09 07 09 05 03 0f 0d 0b 03 0d 05 0d\nressu 2    09 03 0e 03 07 0a 00 08 0b 0f 0a 08 07 0e 08 0c 08 07 0a 0d 05 05 08 06 02 0b 01 04 07 0c 0d 0d\nressu 1    13 07 1d 07 0f 15 01 11 17 1f 15 11 0f 1d 11 19 11 0f 15 1b 0b 0b 11 0d 05 17 03 09 0f 19 1b 1b\nressu 2    15 1b 0d 05 0f 1c 04 0c 01 1f 1b 05 07 0d 18 19 04 04 10 06 08 18 14 08 0a 0e 1c 1e 04 15 15 1a\nressu 1    2a 36 1a 0a 1e 38 08 18 02 3f 37 0b 0f 1b 31 33 09 09 21 0d 11 31 29 11 15 1d 39 3d 09 2b 2b 35\nressu 2    27 0f 16 25 24 05 02 0b 37 0d 36 20 1b 0c 08 2e 3b 22 29 30 27 01 28 16 02 05 2b 1c 08 2b 0a 33\nressu 1    4e 1e 2c 4a 48 0a 04 16 6e 1a 6c 40 36 18 10 5c 76 44 52 60 4e 02 50 2d 05 0b 57 39 11 57 15 67\nressu 2    7f 5c 6a 0a 47 3b 40 21 2e 5a 29 0e 3f 12 60 23 4b 45 37 73 77 53 3e 42 70 68 20 49 52 25 58 57\nressu 1    fe b8 d4 14 8e 76 80 42 5c b4 52 1d 7f 25 c1 47 97 8b 6f e7 ef a7 7d 85 e1 d1 41 93 a5 4b b1 af\nressu 2    87 ee b4 41 69 fc 4e 70 0a b3 d6 46 73 40 a0 0c 01 76 64 73 7e 98 0c e3 9a e3 3e b1 c2 b4 88 e2\n00000 87eeb44169fc4e700ab3d6467340a00c017664737e980ce39ae33eb1c2b488e2\n00001 1a6ea6583d89530e1e1455442446f3cf1ef119d28334f674db7ac30757fd0691\n00002 b777adfc58cf9d4bdf8029a6df98ffd44aa4adfc52675306e72a38193a337da7\n00003 c184bde3d90783c51df7ae206a245449f4c9ad78f2fa052c2113543c69753cf0\n00004 c600776f4299a0729aabac97cc07956a6c3b616b499430c7c6165bbba81febaf\n00005 e817ad5bece64ffcb8a7ca1b1d85a3b2eebbec925403d802c11612e99914531e\n00006 619a2e82b7b321608dbf28d67044b542e2bdc3428d098430662f639c5af26963\n00007 e76d4bf95ddd078a958bd537deb70bce2d6df7f8a0b49aa326565e64161acbbb\n00008 736d9bbcae75d5037da8c545b78ff0042ee45b6a337384b8c389276ab7db962f\n00009 94f2f4ef5cd97591af58c3e4669f64386d05f8cc890eb49946ed451372278168<\/code><\/pre>\n\n\n\n<p>Koko ensimm\u00e4inen swap:\u00e4tty blokki DEBUG5c p\u00e4\u00e4ll\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ressu 3    01 00 01 01 01 01 00 00 01 01 00 00 00 00 01 01 01 01 01 01 01 01 00 01 00 01 01 01 00 01 01 00\nressu 3    01 01 00 00 00 01 01 00 00 00 00 01 01 01 00 00 00 00 00 01 01 00 00 01 00 00 01 00 01 01 00 01\nressu 3    00 01 01 01 01 00 00 00 00 00 01 00 00 00 00 00 00 01 00 00 01 00 01 00 01 01 00 01 00 01 00 01\nressu 3    01 00 00 00 00 00 01 00 01 01 00 00 00 01 01 01 01 01 01 01 01 01 01 01 00 00 01 00 01 01 00 01\nressu 3    01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 01 00 01 01 00 01 01 00 00 01 01 01 01 01 01 01 01\nressu 3    01 01 01 01 01 01 00 00 00 00 01 00 00 01 00 01 01 01 01 01 01 00 01 01 01 01 00 01 00 01 01 00\nressu 3    00 00 00 00 01 01 00 00 00 00 01 01 01 00 00 01 01 01 00 01 00 00 00 00 00 00 00 00 01 00 00 01\nressu 3    00 00 01 00 01 00 01 00 01 00 00 01 00 00 00 00 01 00 00 01 00 00 01 00 01 01 01 01 00 00 01 00\nressu 3    01 00 01 00 00 00 00 00 00 01 00 01 01 00 00 01 01 01 00 01 00 01 01 00 01 00 01 00 01 00 00 01\nressu 3    00 01 01 00 00 01 00 01 00 01 00 01 00 00 00 00 00 00 00 00 00 01 00 01 00 00 01 01 00 01 01 00\nressu 3    01 00 01 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 00 01 00 01 01 01\nressu 3    00 00 00 00 00 00 00 00 00 01 01 01 00 01 00 01 00 01 00 01 00 01 00 00 00 00 00 00 00 00 00 00\nressu 3    00 01 00 00 01 00 00 00 01 00 01 01 01 01 00 01 00 01 01 00 01 00 00 01 01 01 01 00 01 01 01 01\nressu 3    01 01 00 00 01 01 01 01 01 01 01 01 00 01 01 01 01 01 00 00 01 01 00 01 01 01 00 01 01 01 00 00\nressu 3    01 00 01 01 01 01 01 00 01 01 01 01 01 00 01 00 01 00 01 01 01 00 01 00 00 00 00 00 01 01 01 00\nressu 3    01 01 00 01 00 01 00 01 01 01 00 00 00 01 01 00 01 00 00 00 01 01 00 00 01 01 00 01 00 01 00 01\nressu 3    00 00 00 01 01 00 01 00 00 00 01 01 00 01 00 00 00 00 00 01 01 01 01 01 01 01 00 00 00 00 01 01\nressu 3    00 01 01 01 00 00 00 00 01 01 00 01 01 01 01 00 00 00 01 00 00 01 01 01 01 00 00 00 01 01 00 00\nressu 3    01 01 00 00 01 00 01 01 00 00 01 01 00 01 01 00 01 01 00 01 01 00 00 01 01 01 00 00 00 00 01 00\nressu 3    00 00 01 01 00 00 00 01 00 00 00 01 00 00 00 01 00 01 01 00 00 00 01 00 00 00 01 00 00 00 00 01\nressu 3    01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 01 00 00 01 01 01\nressu 3    00 01 01 01 01 00 01 01 01 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 01\nressu 3    01 01 01 01 01 01 01 01 01 01 00 01 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 01 01 01\nressu 3    01 00 01 00 00 00 01 01 01 01 01 01 01 01 01 00 01 01 01 01 01 01 00 01 00 00 00 00 00 00 00 00\nressu 3    01 00 00 00 01 01 01 01 01 01 01 00 01 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 01 01 01 00\nressu 3    01 01 01 01 01 01 00 00 00 00 00 01 01 01 01 01 00 00 01 01 01 01 01 01 00 00 00 00 00 01 01 01\nressu 3    01 00 00 00 00 00 00 01 00 00 00 00 01 00 00 01 00 01 01 00 01 01 00 00 00 01 01 01 01 01 00 00\nressu 3    00 01 01 01 01 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 01 01 01 01 00 00\nressu 3    00 00 00 00 01 01 01 00 01 00 00 00 00 00 01 01 01 01 01 01 00 00 00 00 01 01 01 01 00 01 00 00\nressu 3    00 01 00 01 01 01 01 00 00 00 01 01 01 01 00 00 00 00 00 00 00 01 01 01 00 00 01 00 00 00 00 01\nressu 3    00 00 00 00 01 00 00 00 00 01 01 00 00 01 01 01 01 00 00 00 00 00 01 00 00 01 00 00 01 01 00 00\nressu 3    01 01 00 00 01 00 00 01 00 01 00 00 01 00 00 00 01 00 00 00 01 01 00 00 00 00 00 00 00 00 00 01<\/code><\/pre>\n\n\n\n<p>Edellist\u00e4 DEBUG5C:ll\u00e4 tehty\u00e4 blokkia voi tietenkin verrata seuraavaan ressulla tehtyyn blokkiin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu -w32 -l32 --lim2 -x\n00000  0 0 0 1 0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 0 1 1 0\n00001  1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 0 0\n00002  1 0 1 0 1 0 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 1 1\n00003  1 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0\n00004  1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1\n00005  1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0\n00006  0 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 0\n00007  0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 1 1 0 1\n00008  0 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0\n00009  1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1\n00010  0 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 1 0 0 1\n00011  0 1 1 0 0 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 0 1 1 0 0 0 1 0 0 1 0 0\n00012  0 1 0 0 1 1 1 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0 0 1 1\n00013  0 1 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 1\n00014  1 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1\n00015  1 1 1 0 1 1 1 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 1\n00016  0 0 1 0 1 1 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 0 0\n00017  0 0 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 1\n00018  1 0 0 1 1 1 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0\n00019  0 1 1 1 0 1 1 1 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1 0 0 1 0 0\n00020  0 1 0 0 0 1 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0\n00021  1 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 1 0\n00022  1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 1\n00023  0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0\n00024  0 1 0 1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 0 0 1 0\n00025  0 1 1 1 1 0 0 1 0 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 1 1 0 0 1\n00026  1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 1 0\n00027  0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 0 0\n00028  0 1 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0\n00029  0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1 1 0 0 0\n00030  0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1\n00031  1 0 1 1 1 1 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 1 1<\/code><\/pre>\n\n\n\n<p>Vihdoinkin pseudoressu:n koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define PSEUDORESSU_LIMIT 1048576 \/\/ limit between rekeys\n#define TOPUP_BYTES 32*1024 \/\/ bytes between topups\n#define TOPUP_SIZE 32 \/\/ topup size in bytes (256 bits)\n#define aTOPUP_TWICE 2\n\nstatic unsigned char pseudoressu_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void pseudoressu_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();  \n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash));\n}\n\nstatic void pseudoressu_addrandomness(int size, unsigned char *buffer)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashUpdate(&amp;hash, buffer, size);\n  HashFinal(pseudoressu_key, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash));\n}\n\n#define aDEBUG23 2\n\nstatic void pseudoressu_topup()\n{\n  unsigned char topup&#91;TOPUP_SIZE]; \/\/ 256 bits\n\n  ressu_genbytes(sizeof(topup), topup);\n#ifdef DEBUG23\n  ressu_dump(\"topup\", sizeof(topup), topup, 32);\n#endif\n  pseudoressu_addrandomness(sizeof(topup), topup);\n\n  memset(&amp;topup, 0, sizeof(topup));\n}\n\nvoid pseudoressu_bytes(int size, unsigned char *buffer) \/\/ JariK 2022\n{\n  unsigned int n, blockbytes = 0;\n  unsigned char digest&#91;HashLen]; \/\/ 256 bits\n  static int init = 1, topup_counter = 0;\n\n  if(verbose)\n    fprintf(stdout,\"pseudoressu\");\n\n  while(size &gt; 0) {\n\n    if(topup_counter &lt;= 0) {\n      if(init) {\n\tressu_genbytes(sizeof(pseudoressu_key), pseudoressu_key); \/\/ set first key\n\n#ifdef DEBUG23\n\tressu_dump(\"key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n\n\tinit = 0;\n      }\n      pseudoressu_topup(); \/\/ add randomness to key\n#ifdef TOPUP_TWICE\n      pseudoressu_topup(); \/\/ add randomness to key\n#endif\n      \n      topup_counter = TOPUP_BYTES;\n      blockbytes = 0;\n    } \/\/ end of if(topup_counter &lt;= 0)\n    \n    pseudoressu_internalbytes(digest); \/\/ get random bits using the key\n\n    n = (size &lt; sizeof(digest) ? size : sizeof(digest));\n\n#ifdef DEBUG23\n    ressu_dump(\"olddata\", n, buffer, 32);\n    ressu_dump(\"bytes\", n, digest, 32);\n#endif\n    \n    for(int c = 0; c &lt; n; c++)\n      buffer&#91;c] ^= digest&#91;c];\n\n#ifdef DEBUG23\n    ressu_dump(\"newdata\", n, buffer, 32);\n#endif\n    \n    if(verbose) {\n      fprintf(stdout,\" \");\n      for(int c = 0; c &lt; n; c++)\n\tfprintf(stdout,\"%02x\", digest&#91;c]);\n      newressu_output = 1;\n    }\n    \n    buffer += n;\n    size -= n;\n\n    blockbytes += n;\n    if(blockbytes &gt;= PSEUDORESSU_LIMIT &amp;&amp; size &gt; 0) {\n      pseudoressu_internalbytes(pseudoressu_key); \/\/ replace key with new one\n\n#ifdef DEBUG23\n      ressu_dump(\"key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n\n      blockbytes = 0;\n    }\n\n    topup_counter -= n;\n  } \/\/ end of while(size&gt;0)\n  \n  pseudoressu_internalbytes(pseudoressu_key); \/\/ replace key with new one\n\n#ifdef DEBUG23\n  ressu_dump(\"key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Satunnaislukuja k\u00e4ytt\u00e4en pseudoressua:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --pseudoressu\n00000 84853369290958902675757388129617632217440385931707856776591439954\n00001 84069858194199352061363652567853332957999714525446940392234062860\n00002 06427212315998791561126209640856360958935692530455051657986936746\n00003 99723974440113428246576863396953005265581100052913290239102752500\n00004 63388725437541198987187227629631506871622828013283331007442216631\n00005 62030931043545661111647127241062935062281796958567659952167029594\n00006 47921575029802383061270050124800729975762794596462783830401317795\n00007 52987926964317577756871259541040138838013643538942551182236203384\n00008 24214738687464482704041761961902906703331010263554656580505243598\n00009 70022632015150824436120131748799624755065262077649254711408046279<\/code><\/pre>\n\n\n\n<p>Newressu:un on lis\u00e4tty &#8211;rdrand ja &#8211;rdseed kytkimet, jotka antavat satunnaisbitit k\u00e4ytt\u00e4en Intel (ja Amd) -piirien sis\u00e4ist\u00e4 satunnaislukuominaisuutta.<\/p>\n\n\n\n<p>Aluksi m\u00e4\u00e4ritell\u00e4\u00e4n fort.h:ssa k\u00e4ytet\u00e4\u00e4nk\u00f6 prosessorin satunnaisbittitoimintoa: Voit itse arvioida haluatko k\u00e4ytt\u00e4\u00e4 niit\u00e4 ja poistaa &#8216;a&#8217;:t #define kent\u00e4n nimen alusta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n#define aUSE_RDRAND 2\n#define aUSE_RDSEED 2\n...<\/code><\/pre>\n\n\n\n<p>Sitten komentorivikytkimet ohjelman parametreista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int main(int argc, char *argv&#91;])\n{\n...\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n    if(!strncmp(\"-\", argv&#91;c], 1)) {\n...\n#ifdef USE_RDRAND\n      } else if(!strcmp(\"--rdrand\", argv&#91;c])) {\n\tinput = INPUT_RDRAND;\n\n#endif\n#ifdef USE_RDSEED\n      } else if(!strcmp(\"--rdseed\", argv&#91;c])) {\n\tinput = INPUT_RDSEED;\n\n#endif\n...\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 newressu_genbyte(), jolla luetaan yksi satunnaismerkki:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_genbyte()\n{\n...\n#ifdef USE_RDRAND\n    else if(input == INPUT_RDRAND) \/\/ intel rdrand\n      rdrand_bytes(sizeof(gent), gent);\n#endif\n#ifdef USE_RDSEED\n    else if(input == INPUT_RDSEED) \/\/ intel rdseed\n      rdseed_bytes(sizeof(gent), gent);\n#endif\n...\n}<\/code><\/pre>\n\n\n\n<p>Sitten edellisen kutsumat rdrand_bytes() ja rdseed_bytes() ja niihin liittyv\u00e4t funktiot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void _cpuid(unsigned int leaf, unsigned int subleaf,\n\t    unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)\n{\n  asm volatile(\"cpuid\"\n\t       : \"=a\" (*a), \"=b\" (*b), \"=c\" (*c), \"=d\" (*d)\n\t       : \"a\" (leaf), \"c\" (subleaf) );\n}\n\nint _is_cpu_vendor(unsigned char *cpuvendor)\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(0, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n\n  if(memcmp((char *)(&amp;b), cpuvendor,4) == 0 &amp;&amp;\n     memcmp((char *)(&amp;d), cpuvendor+4,4) == 0 &amp;&amp;\n     memcmp((char *)(&amp;c), cpuvendor+8,4) == 0)\n    ok = 1;\n\n  return(ok);\n}\n\n#endif\n\n#ifdef USE_RDRAND\n\nint _has_rdrand()\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(1, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((c &amp; 0x40000000) == 0x40000000) {\n    ok = 1;\n  }\n\n  return(ok);\n}\n\nint _rdrand_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdrand %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdrand_bytes(int buflen, unsigned char *buf)\n{\n  int c, n, ret = 0;\n  unsigned long l;\n\n  if(verbose) {\n    if(newressu_output == 1)\n      fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdrand()) {\n    if(verbose)\n      fprintf(stdout,\"Intel rdrand\");\n    ret = 1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdrand()) {\n    if(verbose)\n      fprintf(stdout,\"AMD rdrand\");\n    ret = 1;\n  }\n  \n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries = 0;\n\n      while(++tries &lt; 100) {\n\tif((ret = _rdrand_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n\t\/\/fprintf(stdout,\" %016lu\",l);\n      }\n\n      if(verbose) {\n\tfprintf(stdout,\", t:%d \", tries);\n\tnewressu_output = 1;\n      }\n\n      if(ret == 0)\n\tbreak;\n\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n\n      if(verbose) {\n\tfor(c = 0; c &lt; sizeof(l); c++)\n\t  fprintf(stdout,\"%02x\", ((unsigned char *)&amp;l)&#91;c]);\n\tnewressu_output = 1;\n      }\n\n      memcpy(buf, (unsigned char *)&amp;l, n);\n\n      buf += n;\n      buflen -= n;\n    }\n  }\n\n  if(verbose &amp;&amp; newressu_output) {\n    fprintf(stdout, \"\\n\");\n    newressu_output = 0;\n  }\n\n  return(ret);\n}\n\n#endif \/\/ #ifdef USE_RDRAND\n\n#ifdef USE_RDSEED\n\nint _has_rdseed()\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(7, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((b &amp; 0x40000) == 0x40000) {\n    ok = 1;\n  }\n\n  return(ok);\n}\n\nint _rdseed_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdseed %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdseed_bytes(int buflen, unsigned char *buf)\n{\n  int c, n, ret = 0;\n  unsigned long l;\n\n  if(verbose) {\n    if(newressu_output == 1)\n      fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdseed()) {\n    if(verbose)\n      fprintf(stdout,\"Intel rdseed\");\n    ret = 1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdseed()) {\n    if(verbose)\n      fprintf(stdout,\"AMD rdseed\");\n    ret = 1;\n  }\n\n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries = 0;\n\n      while(++tries &lt; 1000) {\n\tif((ret = _rdseed_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n\t\/\/fprintf(stdout,\" %lu\",l);\n      }\n\n      if(verbose) {\n\tfprintf(stdout,\", t:%d \", tries);\n      }\n\n      if(ret == 0)\n\tbreak;\n\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n\n      if(verbose) {\n\tfor(c = 0; c &lt; sizeof(l); c++)\n\t  fprintf(stdout,\"%02x\",((unsigned char *)&amp;l)&#91;c]);\n\tnewressu_output = 1;\n      }\n\n      memcpy(buf, (unsigned char *)&amp;l, n);\n\n      buf += n;\n      buflen -= n;\n    }\n  }\n\n  if(verbose &amp;&amp; newressu_output) {\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  return(ret);\n}\n\n#endif \/\/ #ifdef USE_RDSEED<\/code><\/pre>\n\n\n\n<p>Malliksi satunnaismerkkej\u00e4 k\u00e4ytt\u00e4en &#8211;rdrand kytkint\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --rdrand\n00000 57048164604700389892252604030891636280086112647667058413598950180\n00001 85367873337798713870018921407256662622610378059375065346728579858\n00002 40986136534533462054903474522649995512196495543741784079574936983\n00003 19055247425244842196365427052268075190944922987923879712193930459\n00004 21073317923966805747341619816756386934943889348941261188118170090\n00005 84441244015826068846216962049544449876189313909490716280827133529\n00006 89457709125843616301547827199781195854625633078477767222494900843\n00007 26441810410958757585870825129671642480172920546092127710214865492\n00008 92825666443631689925831354003095669316518706333179728966151922253\n00009 38425570261919457665391336241936521204556331228537091197184239827<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 satunnaismerkkej\u00e4 k\u00e4ytt\u00e4en &#8211;rdseed kytkint\u00e4<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --rdseed\n00000 12575858142151541705315577158406477909851976391447353896413900561\n00001 31060686344418670883795387123181915659843252785862515386243566233\n00002 37717242735083622828533570787786938380359683416949578017028253663\n00003 76962160083573864191170336613298614371660291690167147688816903087\n00004 97599344559430802834845481925548516864857260161367980227215829024\n00005 12924393487151440110103592153782827999940152135987584643269997020\n00006 42239941915393566338139392085782443821230059081997751313044879649\n00007 84190993998746466726787014147375771575146210681898092888312165521\n00008 57327160340778195555246548554777557059408338779546380301502448897\n00009 04224922038814950584933722703301666911868454852489894234206320375<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty hindi satunnaislukuaakkosiin kieliin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --hin\n00000 \u092a\u0920\u091d\u0941\u0928\u092b\u091e\u094c\u093f\u094d\u0940\u0930\u092e\u091e\u092a\u0906\u093f\u0928\u0930\u0935\u092b\u0939\u0928\u0938\u091c\u0915\u0917\u0922\u091f\u0923\u0925\u0907\u0949\u0909\u0918\u092f\u0925\u0908\u0935\u0936\u0914\u091b\u0914\u0920\u0926\u094c\u0947\u0949\u093f\u094d\u091d\u0932\u090a\u090a\u0921\u091b\u0930\u0916\u0949\u0910\u0920\u0941\u0925\u0921\n00001 \u0949\u0936\u094c\u093e\u0943\u0945\u092b\u0940\u090a\u0903\u0928\u090b\u0915\u0928\u0940\u094c\u0928\u092d\u0920\u0930\u0938\u0945\u0924\u091a\u091a\u092e\u0920\u091d\u0916\u092b\u0911\u0930\u0937\u0922\u0917\u0945\u0940\u0928\u0905\u091f\u091c\u0908\u091a\u0920\u0901\u0910\u092c\u0930\u092d\u0935\u0949\u094b\u092a\u0942\u092c\u0947\u094d\u0932\u091e\u0915\u092c\u0905\u0907\u092b\n00002 \u0909\u094d\u091a\u0940\u090f\u0939\u0903\u0923\u0945\u092d\u092f\u0930\u0948\u0910\u0923\u0916\u0932\u0941\u090b\u093f\u091a\u094c\u094c\u0903\u0922\u0908\u091d\u094b\u0901\u0916\u092b\u0917\u092d\u0936\u0910\u091b\u090a\u0907\u0918\u0943\u0909\u0915\u0935\u0917\u0909\u0937\u091f\u0906\u0921\u093c\u092a\u092d\u091b\u092b\u091f\u0949\u0916\u0925\u094c\u093c\u0909\u092c\u0940\u0920\n00003 \u0939\u091f\u090b\u0939\u0925\u092b\u092e\u0917\u094c\u0942\u0909\u090f\u0902\u094c\u091c\u0947\u0947\u0932\u090f\u094c\u0937\u0915\u0910\u0907\u0930\u090f\u0948\u092a\u0935\u0926\u092e\u0927\u0945\u091a\u090a\u0916\u091a\u093f\u091a\u0917\u0927\u0935\u092c\u092e\u091f\u0935\u0917\u092e\u0908\u0906\u0905\u094d\u0922\u094d\u0903\u092d\u094b\u091a\u0932\u091f\u0925\u093c\u090b\u090f\n00004 \u0940\u093f\u092b\u0924\u0902\u091f\u092a\u094d\u0940\u093f\u0921\u0901\u092d\u0935\u0926\u0917\u0903\u094d\u092e\u0917\u090b\u090f\u0917\u0906\u0915\u0910\u0936\u094d\u0906\u0922\u0911\u0947\u0905\u091a\u092e\u0923\u0938\u0910\u0938\u094b\u0907\u0930\u094d\u0947\u090f\u092f\u0915\u094c\u0940\u0918\u091d\u0925\u092b\u0915\u0915\u0903\u0923\u091b\u0913\u0940\u090f\u0945\u092c\u0926\n00005 \u0905\u091f\u093f\u0922\u091b\u0927\u0947\u090b\u0920\u0911\u0914\u090f\u091b\u0945\u091d\u0922\u093f\u0943\u0924\u0945\u0927\u0916\u090b\u093e\u092b\u0923\u0927\u092a\u0907\u091a\u0923\u0947\u0915\u092c\u091b\u0908\u0945\u0947\u091e\u093c\u0922\u0935\u093f\u0902\u0915\u0917\u090b\u0911\u0924\u091c\u0940\u0941\u0924\u092c\u0907\u093c\u094d\u091b\u0941\u091b\u0908\u0913\u0927\u092b\n00006 \u0927\u090b\u0925\u093e\u0907\u091e\u0917\u0917\u0905\u0920\u0913\u092f\u094c\u0935\u091f\u0917\u090f\u0945\u0947\u0917\u0911\u0910\u0921\u090f\u090f\u091e\u091e\u091f\u0935\u0949\u0924\u0901\u0949\u093f\u091c\u093e\u092e\u0920\u0941\u0922\u0911\u0932\u0936\u091b\u0926\u0909\u091b\u0949\u0920\u091f\u091c\u0923\u0942\u092f\u0917\u094c\u0948\u0948\u0940\u0936\u0918\u0947\u0949\u091d\n00007 \u0921\u090b\u0915\u0928\u0915\u0909\u0905\u0906\u0910\u093c\u091c\u0928\u0905\u0937\u090a\u093e\u091e\u093f\u0907\u091c\u0940\u0909\u0917\u0902\u091a\u0932\u093c\u0901\u092c\u0920\u0940\u092e\u092b\u0920\u0945\u0921\u0939\u0908\u0911\u0924\u0939\u0902\u0935\u091f\u0924\u0902\u090a\u093f\u0927\u0916\u094b\u090b\u0923\u093e\u0913\u0943\u091c\u091e\u0915\u0916\u090b\u0947\u090f\u0940\n00008 \u0902\u0913\u0923\u093c\u0941\u091a\u0937\u091b\u0937\u0913\u091e\u090f\u092b\u091a\u0911\u094c\u091c\u0942\u090b\u092b\u093e\u0928\u0905\u0907\u0920\u0920\u0920\u0907\u0945\u0906\u0909\u0902\u090a\u0907\u090a\u0935\u094c\u0901\u0924\u0935\u091f\u0921\u0937\u0930\u091b\u0918\u092a\u0903\u0907\u090b\u091a\u091d\u0939\u0901\u0914\u091d\u0903\u090f\u091b\u0914\u0940\u091c\u0935\u0915\n00009 \u0901\u090f\u0911\u0921\u0907\u0949\u0914\u093c\u094d\u093f\u092e\u0943\u0913\u092e\u093e\u0926\u0908\u0941\u0923\u0920\u0947\u0918\u0915\u0927\u0947\u0915\u0913\u0915\u093e\u091a\u092e\u0936\u0916\u090b\u0943\u0901\u0916\u0936\u0922\u092c\u094b\u092b\u0941\u0935\u0932\u0924\u093e\u0945\u0948\u0930\u091d\u092b\u0926\u0916\u0911\u091d\u0949\u0936\u0918\u0943\u0901\u0928\u0947\u0918<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 koodi newressuun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n      } else if(!strcmp(\"--ind\", argv&#91;c]) \/\/ not ready\n\t     || !strcmp(\"--hin\", argv&#91;c])) { \/\/ Hindi alphabet\n\t\/\/unsigned char *signs = \"\u0900\u0901\u0902\u0903\u093a\u093b\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d\u094e\u094f\u0955\u0956\u0957\u0962\u0963\u0951\u0952\u0953\u0954\";\n\tdigits =\n\t  \"\u0904\u0905\u0906\u0907\u0908\u0909\u090a\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c\u091d\u091e\u091f\u0920\u0921\u0922\u0923\"\n\t  \"\u0924\u0925\u0926\u0927\u0928\u0929\u092a\u092b\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093d\u0950\u0958\u0959\u095a\u095b\u095c\"\n\t  \"\u095d\u095e\u095f\u0960\u0961\u0964\u0965\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0970\u0971\u0972\u0973\u0974\u0975\u0976\u0977\u0978\u0979\u097a\u097b\u097c\u097d\u097e\"\n\t  \"\u097f\"; \/\/ 97 characters\n\n\t\/\/digits_add_limits(&amp;digits,0x900,0x97f);   \/\/ Hindi (0900-097f)\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n...<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty viel\u00e4 somalian ensimm\u00e4inen versio (seuraavassa versiossa ei viel\u00e4 kaksoiskirjaimia: KH, SH, DH): (mukana my\u00f6s columns rivit, joista lis\u00e4\u00e4 seuraavassa kappaleessa:)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --som --columns\n---------1111111111222222222233333333334444444444555555555566666666667\n1234567890123456789012345678901234567890123456789012345678901234567890\n======================================================================\n00000 GDSBGHQOOAOHRJNLYGARTSELJDJLAJYYOTLEWEBWRXDNLQWTTMRYFOTJHGTWTYNF\n00001 TCDCJXCNLCJJLCJORFYNALEYNTQNTKGTKAJNJFACAECQTJWKJLFJTXMLFMMYQCCC\n00002 CWCYJKNEMGNQXMNRQYYAYQXDXSQEWWNSESTNGEGMBMKHCROKBMKCLAOSHCOJMGFA\n00003 ARBTQCJNJOQOBRRGCXTMHNTOETNJXTOSRGSRFAOLKXGOLXDHGTCTBCCNTJFQCKAS\n00004 WXGKLSXHEXXTXLKQRQSDYRWRTHXQBBKGTADDEXNGCXFBSROJXEHSDQEBLSCYCQQR\n00005 HGOOEEKYHHEFGYGLQLCOXSNMSTGOKBQGJKHJJYJTOJOWNDGBGELFFFXWWHQGCGTG\n00006 SJTQFSHOEYARAHOQSFBKSMXYOFXAEHFATSTYRAEWTNOSDQDATJNAGTXCYFCKCQHX\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 koodi somalian ensimm\u00e4isen version kirjaimiin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--som\", argv&#91;c]) ||\n\t\t!strcmp(\"--SOM\", argv&#91;c]) ||\n\t\t!strcmp(\"--SO\", argv&#91;c])) { \/\/ Somalia alphabet\n\n#ifdef KOK\n\t\/\/ A, B, T, J, X, KH, D, R, S, SH, DH, C, G, F, Q, K, L, M, N, W, H, Y, E, and O\n\tdigitsstrings = \"A\", \"B\", \"T\", \"J\", \"X\", \"KH\", \"D\", \"R\", \"S\", \"SH\", \"DH\", \"C\", \"G\", \"F\", \"Q\", \"K\", \"L\", \"M\", \"N\", \"W\", \"H\", \"Y\", \"E\", \"O\", \"\";\n\n\tint first = 1;\n\tunsigned char **pp;\n\tpp = digitsstrings;\n\tfor(c = 0; strcmp(*pp, \"\"); c++) {\n\t  if(!first)\n\t    fprintf(stdout,\", \");\n\t  fprintf(stdout,\"%s\", *pp);\n\t  first = 0;\n\t  pp++;\n\t}\n\t\/\/ missing KH SH DH\n#endif\n\tdigits = \"ABTJXDRSCGFQKLMNWHYEO\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty &#8211;columns komentoriviparametri, jolla voidaan tulostaa sarakkeittain sarakkeen numero: ajo esimerkki<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---------11111111112222222222333333333344444444445555555555666666666677\n12345678901234567890123456789012345678901234567890123456789012345678901\n=======================================================================\n00000 22258382806296729238178486166796544611755807164847927666922883010\n00001 28418563167711867913647921768757420667110694576793471041747264318\n00002 99804558335755889341259131631520927482583107862745929217530498421\n00003 51760111177576244043527804917085407731383726282400768462117274375\n00004 89648866862627378375043043971820779839978322370961568999705923913\n00005 29058447822637409075394304381942641680239167678291358293770305216\n00006 02068139412914507088518193191859344515532139033119514656041976727\n<\/code><\/pre>\n\n\n\n<p>Ja koodi: (huomaa reilusti yli menev\u00e4 maksimi sarakkeiden m\u00e4\u00e4r\u00e4, ylin rivi kertoo miljoonat. Toki vasta ensimm\u00e4inen rivi joka tarvitaan tulostetaan. mallilistassa ensimm\u00e4isell\u00e4 rivill\u00e4 on kymmenet)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  \/\/\n  \/\/ look thru command line parameters\n  \/\/\n  \n  for(c = 1; c &lt; argc; c++) {\n...\n     } else if(!strcmp(\"--columns\", argv&#91;c])) {\n\tcolumns = !columns; \/\/ print column numbers\n...\n     }\n }\n...\nif(columns) {\n\n    \/\/---------11111111112222222222333333333344444444445555555555666666666677\n    \/\/12345678901234567890123456789012345678901234567890123456789012345678901\n    \/\/=======================================================================\n    \/\/00000 86747100388687087416829400778878989202760594993130062980826178851\n    \/\/00001 36862623069143814543525935285460059703805218323534266522497684582\n\n    int digit, clines = 0, nonzero;\n    for(c = 1000000; c &gt;= 1; c \/= 10) { \/\/ lines, 100000's, 10000's, 1000's ... 1's\n      if(pchars &lt; c)\n\tcontinue;\n      nonzero = 0;\n      for(d = 1; d &lt;= pchars; d++) { \/\/ column numbers\n\tdigit = (d \/ c) % 10;\n\tif(digit != 0)\n\t  nonzero = 1;\n\tif(nonzero)\n\t  fprintf(stdout,\"%d\", digit); \/\/ nonzero digits after first nonzero\n\telse\n\t  fprintf(stdout,\"-\"); \/\/ zeroes in beginning of row\n      }\n      fprintf(stdout,\"\\n\");\n      clines++;\n    }\n    for(d = 1; d &lt;= pchars; d++)\n      fprintf(stdout,\"=\");\n    fprintf(stdout,\"\\n\");\n    clines++;\n    lines -= clines\n  } \/\/ if(columns\n\n<\/code><\/pre>\n\n\n\n<p>Muutettu komentoriviparametrien tiedoston kokoa m\u00e4\u00e4rittelev\u00e4t parametrit samankaltaisiksi kaikissa testi ja newressu.c ohjelmissa: aluksi newressu.c:n tarvitsemat muuttujat: _set loppuiset parametrit muutetaan ykk\u00f6siksi jos ko parametri m\u00e4\u00e4ritell\u00e4\u00e4n.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned long long filesize = FILESIZE, blocks = BLOCKS;\nunsigned int blocksize = BLOCKSIZE;\nint filesize_set = 0, blocks_set = 0, blocksize_set = 0;<\/code><\/pre>\n\n\n\n<p>Sitten komentoriviparametri iffit: ensimm\u00e4inen kappale m\u00e4\u00e4rittelee &#8211;filesize parametrin, toinen kappale &#8211;blocksize parametrin ja viimeinen &#8211;blocks kappale m\u00e4\u00e4rittelee &#8211;blocks parametrin (blokkien lukum\u00e4\u00e4r\u00e4).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--blocksize\", argv&#91;c], 11)) {\n\tif(*(argv&#91;c] + 11) != '\\0') {\n\t  blocksize = getlonglong(argv&#91;c] + 11);\n\t} else if(c + 1 &lt; argc) {\n\t  blocksize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tblocksize_set = 1;\n\t\n      } else if(!strncmp(\"--blocks\", argv&#91;c], 8)) {\n\tif(*(argv&#91;c] + 8) != '\\0') {\n\t  blocks = getlonglong(argv&#91;c] + 8);\n\t} else if(c + 1 &lt; argc) {\n\t  blocks = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tblocks_set = 1;<\/code><\/pre>\n\n\n\n<p>Parametrien tarkistus ja puuttuvien laskenta: huomaa exfat korjaus, jossa tarkastetaan ett\u00e4 blokin koko ei ylit\u00e4 megaa merkkej\u00e4, ja jos ylitt\u00e4\u00e4 se py\u00f6ristet\u00e4\u00e4n megaan ja blokkien m\u00e4\u00e4r\u00e4 ja tiedoston koko lasketaan uudelleen. Ensimm\u00e4inen kappale laskee puuttuvan parametrin, ensimm\u00e4isen\u00e4 lasketaan tiedoston koko (filesize), jos sit\u00e4 ei ole parametreissa, sitten blokin koko ja viimeisen\u00e4 blokkien lukum\u00e4\u00e4r\u00e4, jos niit\u00e4 ei ole annettu parametrin\u00e4.  <\/p>\n\n\n\n<p>Toinen kappale laskee miljoonaa merkki\u00e4 suuremman blokin koon miljoonaan, ja laskee uudelleen blokkien m\u00e4\u00e4r\u00e4n ja tiedoston koon (kun blokin koko laskee, my\u00f6s blokkien m\u00e4\u00e4r\u00e4 ja tiedoiston koko muuttuu).<\/p>\n\n\n\n<p>Kolmannessa kappaleessa tarkistetaan tiedoston koko (filesize) parametrin ylivuoto ja ett\u00e4 blokkeja on v\u00e4hint\u00e4\u00e4n yksi ja blokin koko on ainakin yksi.<\/p>\n\n\n\n<p>Nelj\u00e4tt\u00e4 kappaletta tarvititaan silloin kun tarkistetaan ett\u00e4 tiedoston koko(filesize), blokin koko (blocksize) ja blokkien m\u00e4\u00e4r\u00e4 (blocks) parametrit on annettu oikein, kun ne on kaikki sy\u00f6tetty. Toki se viel\u00e4 lopputarkastaa my\u00f6s lasketut parametrit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  \/\/ calculate missing file size parameters\n  \n  if(!filesize_set)\n    filesize = blocks * blocksize;\n  else if(!blocksize_set) {\n    blocksize = (filesize + blocks - 1) \/ blocks; \/\/ round up\n    filesize = blocks * blocksize;\n  } else if(!blocks_set) {\n    blocks = (filesize + blocksize - 1)\/ blocksize; \/\/ round up\n    filesize = blocks * blocksize;\n  }\n\n#define aEXFAT_FIX 2 \/\/ on for now\n  \n#ifdef EXFAT_FIX\n\n  if(blocksize &gt; KILO * KILO) { \/\/ max \"blocksize\" 1m (exfat)\n    blocksize = KILO * KILO;\n    blocks = (filesize + blocksize - 1) \/ blocksize;\n    filesize = blocks * blocksize;\n  }\n\n#endif\n  \n  if(filesize != blocks * blocksize ||\n     blocks &lt; 1 || blocksize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): mismatched parameters\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n  \n  if(filesize \/ blocks != blocksize) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): parameter overflow\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n<\/code><\/pre>\n\n\n\n<p>Parametrien k\u00e4sittelyss\u00e4 k\u00e4ytetty getlonglong() funktio: getlonglong() k\u00e4ytt\u00e4\u00e4 getdigit():i\u00e4 lukeakseen yhden numeromuotoisen merkin. T\u00e4ss\u00e4 numero voi mik\u00e4 tahansa numero 0-9 tai kirjain a-z. K\u00e4yt\u00f6ss\u00e4 on vain bin\u00e4\u00e4ri &#8220;01&#8221;, oktaali &#8220;01234567&#8221;, desimaali &#8220;0123456789&#8221;, heksa &#8220;0123456789abcdef&#8221;.<\/p>\n\n\n\n<p>getlonglong():n ensimm\u00e4inen osuus lukee asiakkaan parametrin numeroj\u00e4rjestelm\u00e4n (0b&#8230;, 0o&#8230;, 0d&#8230; tai 0x&#8230;), (esimerkiksi (0b1111 on 15, 0o10 on 8, 0xff on 255). Jos numeroj\u00e4rjestelm\u00e4\u00e4 ei ole annettu oletuksena on desimaali.<\/p>\n\n\n\n<p>Toinen osuus laskee yhteen asiakkaan parametrin numeromerkit (esimerkiksi 8192) ja laskee ne yhteen huomioiden asiakkaan antaman numeroj\u00e4rjestelmin (bin\u00e4\u00e4ri jne).<\/p>\n\n\n\n<p>Kolmas osuus lukee asiakkaan antaman kertoimen (kilo, mega, giga, tera, peta tai eksa) esimerkiksi 1k, 1m, 2t. 8 merkin pituiseen kokonaislukuun mahtuu 15 eksaa ja rapiat.<\/p>\n\n\n\n<p>Nelj\u00e4s osuus tarkistaa ennettavan parametrin ylivuodon ja ynn\u00e4\u00e4 samaan parametriin liittyv\u00e4t numero osuudet yhteen (esimerkiksi &#8211;filesize1g1m). Lopuksi poistetaan b tai &#8216;B&#8217; lauseista kuten &#8216;100kb&#8217; tai &#8216;1gb&#8217;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int getdigit(unsigned char *p)\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n#define DEBUG32\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nunsigned long long getlonglong(unsigned char *p2)\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value: %d\", digit);\n      fprintf(stderr,\", base: %d\", base);\n      fprintf(stderr,\", ll: %llu\", prevll);\n      fprintf(stderr,\", multiplier: %llu\", multiplier);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb, 1gb or 1mb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value: %d\", digit);\n    fprintf(stderr,\", base: %d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n\n  return(totll);\n}<\/code><\/pre>\n\n\n\n<p>DEBUG32 on oletuksena p\u00e4\u00e4ll\u00e4 ja se tulostaa rivin n\u00e4ist\u00e4 parametrien laskennoista: string kent\u00e4ss\u00e4 on k\u00e4sitelt\u00e4v\u00e4 parametri merkkijonona base on k\u00e4ytt\u00e4j\u00e4n antama numeroj\u00e4rjestelm\u00e4, multiplier on k\u00e4ytt\u00e4j\u00e4n antama kerroin (k, m, g, t, p, e), prevll on asiakkaan antama numero, ll on kerroin * numero, totll on samaan numeroon liittyv\u00e4t numerot yhteens\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --sample --filesize 1g100m --blocksize1k\nstring:'1g100m', base:10(10B), multiplier:1073741824(1G), prevll:1(1B), ll:1073741824(1G), totll:1073741824(1G)\nstring:'1g100m', base:10(10B), multiplier:1048576(1M), prevll:100(100B), ll:104857600(100M), totll:1178599424(~1G)\nstring:'1k', base:10(10B), multiplier:1024(1K), prevll:1(1B), ll:1024(1K), totll:1024(1K)\nblocksize:1024(1K), blocks:1150976(~1M), filesize:1178599424(~1G)\n...\n$ <\/code><\/pre>\n\n\n\n<p>Edellisess\u00e4 kuvassa on haluttu yhden gigan ja sadan megan kokoinen satunnaisbittitiedosto, jossa blokin koko (fwrite:n koko) on 8192. Ensimm\u00e4inen string: rivi edellisss\u00e4 sis\u00e4lt\u00e4\u00e4 1g tiedoston koosta, toinen rivi 100m  tiedoston koosta, ja kolmas rivi 8192 blokin koon. viimeinen blocksize: rivi kertoo viel\u00e4 yhteenvedon asetetuista tiedostokoon parametreista.<\/p>\n\n\n\n<p>Viel\u00e4 aiemmissa ohjelmissa k\u00e4ytetyt aliohjelmat: readablelonglong() tulostaa desimaalikokonaisluvun ja sen suuruusluokan (100g, 10m, 2t jne): toinen aliohjelma fprintfcharacter() tulostaa ufh merkin kokonaisuudessaan: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void readablelonglong(FILE *fp1, unsigned long long ll2)\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Newressuun on lis\u00e4tty uusi merkkijono salausmalli (stream cipher) &#8211;stream, jolla voidaan tehd\u00e4 satunnaisbittej\u00e4 merkkijonosta: seuraavat bitit on tehty merkkijonosta &#8220;kalakala&#8221;. Jatkossa merkkijonosalausta k\u00e4ytet\u00e4\u00e4n tiedoston kirjoituksen tarkastamiseen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --stream --key kalakala\n.\/newressu: stream_open(): randomness from key, key=kalakala\n00000 097007647538070452095222876773364032014848877614885432576274114682\n00001 069076802144253754847369390425580418083695093228828897799956369200\n00002 166962649730107510677372501914913551333963649770546607920656167530\n00003 123872208527077508554473908037757655294059571650948600601580541243\n00004 959069120976810662076442907983660853450311026021709027187795181219\n00005 958500289994828533504137325466090300723020468339411775941540872433\n00006 103918486603641932851463892918552658439592999940967471423412165257\n00007 067647133783366171502688214398736241529441281236178360416684844342\n00008 827011090709785699618541893769244994414243921218781696849617463710\n00009 826005683785268736980725472626588977843361269856648811013296399762\njarik@jarik-HP-250-G8:~\/f\/ressurngd$<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty integriteettitarkistus aina .\/newressun ajon alkuun (DEBUG72). Sit\u00e4 varten on lis\u00e4tty seuraavat koodinp\u00e4tk\u00e4t.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG72 \/\/ default is on\n\t\t     \n#ifdef DEBUG72\t\n  int flagint = 1;\n#endif\n....\n  for(c = 1; c &lt; argc; c++) {\n...\n#ifdef DEBUG72\t\n      } else if(!strcmp(\"--int\", argv&#91;c])) {\n\tflagint = !flagint;\n\t\/\/fprintf(stdout,\"Integrity test skipped...\");\n#endif\n...\n  }\n....\n#ifdef DEBUG72\n  if(flagint) {\n    unsigned char command&#91;128];\n    fprintf(stderr,\"%s: Running integrity test(s)...\",procname);\n    fflush(stderr);\n    sprintf(command,\".\/newressutest14.sh &gt;newressutest14.rnd.`date +%%Y%%m%%d`\");\n    system(command);\n    fprintf(stderr,\" done.\\n\");\n    fflush(stderr);\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Lis\u00e4ksi tuo edellisess\u00e4 kappaleessa k\u00e4ynnistetty scripti newressutest.sh:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/bin\/newressu --int --single --space2 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space3 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space4 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space5 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space6 --newline 5 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s1 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s2 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s3 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s4 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s5 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s6 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s7 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s8 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s9 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s10 -l1 $@\n\/bin\/newressu --int --single --rand -l1 $@\n\/bin\/newressu --int --single --alnum -l1 $@\n\/bin\/newressu --int --single --alpha -l1 $@\n\/bin\/newressu --int --single --graph -l1 $@\n\/bin\/newressu --int --single --lower -l1 $@\n\/bin\/newressu --int --single --punct -l1 $@\n\/bin\/newressu --int --single --upper -l1 $@\n\/bin\/newressu --int --single -d --lim41 -w7 --zero -l1 --lotto$@\n\/bin\/newressu --int --single --1bit -l1 $@\n\/bin\/newressu --int --single --2bits -l1 $@\n\/bin\/newressu --int --single --3bits -l1 $@\n\/bin\/newressu --int --single --oct -l1 $@\n\/bin\/newressu --int --single --4bits -l1 $@\n\/bin\/newressu --int --single --hex -l1 $@\n\/bin\/newressu --int --single --HEX -l1 $@\n\/bin\/newressu --int --single --5bits -l1 $@\n\/bin\/newressu --int --single --6bits -l1 $@\n\/bin\/newressu --int --single --dnk -l1 $@\n\/bin\/newressu --int --single --nor -l1 $@\n\/bin\/newressu --int --single --fin -l1 $@\n\/bin\/newressu --int --single --swe -l1 $@\n\/bin\/newressu --int --single --rus -l1 $@\n\/bin\/newressu --int --single --est -l1 $@\n\/bin\/newressu --int --single --ltu -l1 $@\n\/bin\/newressu --int --single --lva -l1 $@\n\/bin\/newressu --int --single --fra -l1 $@\n\/bin\/newressu --int --single --gbr -l1 $@\n\/bin\/newressu --int --single --usa -l1 $@\n\/bin\/newressu --int --single --ita -l1 $@\n\/bin\/newressu --int --single --eng -l1 $@\n\/bin\/newressu --int --single --deu -l1 $@\n\/bin\/newressu --int --single --grc -l1 $@\n\/bin\/newressu --int --single --jp -l1 $@\n\/bin\/newressu --int --single --jp1 -l1 $@\n\/bin\/newressu --int --single --hir -l1 $@\n\/bin\/newressu --int --single --jp2 -l1 $@\n\/bin\/newressu --int --single --kat -l1 $@\n\/bin\/newressu --int --single --jp3 -l1 $@\n\/bin\/newressu --int --single --cn -l1 $@\n\/bin\/newressu --int --single --kan -l1 $@\n\/bin\/newressu --int --single --kor -l1 $@\n\/bin\/newressu --int --single --ind -l1 $@\n\/bin\/newressu --int --single --hin -l1 $@\n\/bin\/newressu --int --single --som -l1 $@\n\/bin\/newressu --int --single --SOM -l1 $@\n\/bin\/newressu --int --single --SO -l1 $@\n\/bin\/newressu --int --single --braille -l1 $@\n\/bin\/newressu --int --single --dna -l1 $@\n\/bin\/newressu --int --single --DNA -l1 $@<\/code><\/pre>\n\n\n\n<p>Raportti, joka t\u00e4ss\u00e4 tapauksessa kirjoitettiin newressutest14.rnd.* tiedostoon on seuraavankaltainen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>00000   43547 02424  77426 40520  24483 85853  60125 09060  27766 91983\n00000   90226 00953 26685  66371 98917 68085  20508 58887 33858  26510\n00000   36046 40837 05103 72057  02162 62838 77719 36899  29862 14697\n00000   36556 28423 75766 79658 12445  83960 32923 60357 04934 69935\n00000   29071 78822 29171 57055 83957 60222  54011 66685 51620 90995\n00000  x a d N 6 9 1 1 f A X t R p s B Z p B I Z Q E x N R l - f I d y j\n00000  Z3 TR -s UJ dF bm L1 Uf iC w0 _m sK 2k bg vA LU W8 83 3R tA if x2\n00000  F7K Ypn cRV fqT Sgd -nH xCg lfx mKa 1bO AQE OFH pfU Ytq xpH tw6\n00000  -s0J cK8N FZpP rd2c tqQn 3gKJ 4vqB 6mC6 yA97 0S7P 3EBM 30vu LBP5\n00000  2_lY0 N5uo4 Bf_uu EAEaU vyXiT Nm5BD 4004V 8sHqa fTjlL rdgiV IwJQo\n00000  8-2Zwx gVbEem 0Mj1Eg yuUJfx perUOH TGNBnp jaNiOK RulLWh IpfY9P\n00000  K-GfdFW wAsO75R xjhpfXE HxMtnkr sLY1620 zJimadt xYbLTvQ LOqwtmy\n00000  jjDtKyoH MV2tEJ4p 8SywDwv- svDXLQbu Img1Xe-4 vfFnoIQg 81354mXg\n00000  -V7ui7PEs xczU8mdRB LuRUcHPGt XzbIR427y yyDMjByDH v5fDDGYL8\n00000  KNU_kIR7_g R_G2vivdDi urouyAaGdT YdtjjAl-Hj aCJCUgUdnL mx6j3PdM3Z\n00000   41712 25645  39695 88861  41948 33840  36298 59751  77600 74349\n00000 UBWuGDDcGpFkKNo244N5TVrH8TwEsl2eKypdBOIyBDkMoCaKwkT5IwTZo2yYum2dg\n00000 kknksuixobxgyelguaxyknlbkotypickbqfxqcafuyshzflujousbwiykgyaxvfdy\n00000 6EoMqaSuRdDe7m*xZ4-}ND%T';6MmD@KK~sZ`8^Lv*w2$,dv9(SC(.;Nx:6.vib(@\n00000 stshrhhiupnmovnaovkzuifoohqivxyzrahmprolgqhjfbaaeigvueeuoqtqvyofk\n00000 {%~')`%,%#;\\&lt;\"\\#}{#'&lt;?]&lt;)&gt;&gt;_!(:]~;~&gt;=$+|&lt;=!~-!:$,{]:+~.&amp;}))^=!-`|\n00000 HJGGZIRMQRWPXNELYARMBNDJLXCJMIOHEKVCKBQDUAGWJXAYMJTNPMTWNIQTKQMHA\n00000  03 04 14 18 24 29 36\n00000 1110110011100100110111111111011010110010111011110011011001000000\n00000 3102022001303221331223300321321003220321212030231122110223131121\n00000 742074745673401760037715534423267357677510113274147215471160147115\n00000 154564406714644140021565367601517766620126222517076751422000524201\n00000 2e5408c76d6619cfe329f7d133647d9252a5c207fa6591f863998a6711e85570\n00000 04d2c38c643fa8f8307658a931256b3dc878adf7ea1ef6df9387351fe4eabb05\n00000 CC807E1CB27065460191405263BDE3102150881F7E34A5190EE04E69EC6AF271\n00000 D8TV7UC8P601U16IBA6TKUTECL49GV1LLPLAJ5I8G7KDEQ0BOUIUFKIEUCNVHL6K\n00000 j7YBjWvXCovQdzVhONSoCArNTWzg5Gv0OX6jjMbzRi2ZUXHtazO85ZynzF6V-UwB\n00000 zjDzoquNXiaxPTq\u00d8UDCif\u00d8qaGw\u00c6nChKzfVXoKND\u00f8xso\u00c5NmpoCpCAkRqiC\u00c5Ty\u00c5Lnw\n00000 ho\u00c5NMEheh\u00e6SYxktZNhCxvB\u00c5ZLk\u00c5ULXLyePDkobFQO\u00c6cjmuizyUmGrKCA\u00d8uvvRNII\n00000 VE\u00e5R\u00d6tUObVVNoyDC\u00c4jQWO\u00e4lV\u00e4wt\u00c5BAQNWqnYhJCA\u00e5G\u00d6XqHyW\u00e4\u00e5Xf\u00e5YJ\u00f6S\u00f6RNCXEi\n00000 j\u00e4HGrryvoc\u00c4oBVhwA\u00d6\u00c4HKTnMfOzUkw\u00c4lZlxU\u00f6\u00e5hll\u00c4nu\u00c4kjCnLuEryjUiKNVS\u00e5\u00e5t\n00000 \u0439\u042a\u043b\u0446\u0419\u043e\u0449\u044c\u0440\u0446\u0421\u0441\u0419\u044c\u0434\u0440\u044c\u0436\u0442\u0441\u041e\u0444\u0439\u0445\u043d\u042a\u0433\u044d\u0440\u041e\u0439\u042d\u044b\u0417\u0424\u0444\u042d\u0435\u044c\u0429\u044d\u0421\u043b\u0441\u0438\u0415\u041c\u043e\u0430\u0426\u0435\u042b\u0442\u0425\u0451\u043b\u044b\u041b\u042d\u042c\u0430\u041c\u0438\u041e\n00000 UmTNPqcn\u00f6tMmOCLUjZP\u0160maKrqTi\u00f5SKCq\u017d\u00d6mLd\u00fcH\u00e4\u00f6\u00f5mFj\u00dcFe\u00dcl\u00c4jE\u00dcWMgwyej\u00d5qS\n00000 ke\u0173zotDcV\u010c\u0173C\u016ayPmgcCinvuee\u012f\u010d\u0161PIGU\u010cId\u0173sE\u016a\u016azjMS\u0172T\u0172fEFb\u012eI\u017d\u010ds\u017eBn\u016b\u0105g\u010cg\n00000 uM\u0100\u0100bP\u0123VB\u0122bA\u0100\u016amrDhsnh\u0122h\u0101UP\u017e\u012akzPAFd\u0100e\u0137\u013c\u010d\u0136Ch\u0113ljmaaGIR\u0160\u012a\u016aa\u012a\u017d\u013c\u0137JjbtF\n00000 foRubnHSkBtkPRptozSvDkwElsbHIIXerpLqfwzuigBxnSMoUQefFxkCOfXWYnSK\n00000 wDasgHAgMzdATKKUyYiltXbvLgVPgHilhklyyNUNGYTAyBHXYJpktfBUmFVBfnPp\n00000 zTTpcRUDmJLElleTngPqqznspGXOjlibUeafTYPrfhtmOTLvyVgIQlTECHlosAVc\n00000 hzyItLFHUjOfeoiOEqwrkKNLwFjfMzHsGqnQcygUIdJQqgAcqsbjcQfDOOdqJKnr\n00000 BFPJszetXmOVAoloouHdLmrdyePkRnucovlhqWYAKIPeYOoqcqLiMWBcgtFdWXzi\n00000 zQrfpG\u00dfTVS\u00f6BzRYWyRDbieFcNOQniX\u00df\u00e4THRtY\u00f6wPiuaJGQ\u1e9ez\u00e4E\u00dcsSLO\u00e4nTOaKItp\n00000 \u03a0\u03a4\u0391\u039a\u03ba\u03b9\u03a5\u03bd\u03c5\u0397\u03a7\u03be\u0397\u0397\u039a\u03b1\u03a8\u03c7\u03a8\u03b1\u039f\u03c5\u039a\u03b5\u03a0\u03b2\u0393\u0394\u039f\u0399\u03b4\u0394\u039f\u039a\u03a0\u0393\u03ba\u0395\u03b1\u03c6\u03a4\u03b6\u03c8\u0398\u0399\u0392\u03bd\u03b8\u03bc\u03c0\u03b1\u03b4\u03a5\u03a6\u0397\u03b8\u03c6\u03a3\u03c1\u03b1\u0396\u0394\u039d\u03c1\n00000 \u8433\u793a\u67cd\u74ad\u5ffe\u9a52\u863c\u5d30\u6a5a\u5405\u5eca\u8ca0\u7a3d\u90f1\u9fe0\u5104\u550d\u6caa\u77b5\u7029\u99e4\u977f\u7758\u8676\u9a5a\u84a1\u6eeb\u607b\u57e4\u9787\u673f\u90d6\n00000 \u3095\u3096\u3044\u306b\u3063\u3052\u3082\u3050\u3093\u3043\u308a\u304f\u3047\u3059\u3067\u3072\u3085\u3087\u3049\u3096\u3082\u3048\u3091\u3042\u3056\u308a\u306f\u306e\u3048\u308e\u3083\u3046\n00000 \u305b\u3095\u307b\u3078\u3078\u3046\u306f\u3058\u3055\u3052\u3046\u3079\u3074\u3081\u308c\u305f\u3049\u3092\u308f\u3070\u3042\u3093\u305e\u308e\u3072\u304d\u3078\u3096\u3087\u3060\u3080\u308e\n00000 \u30c1\u30fb\u30c7\u30da\u30ab\u30f5\u30f9\u30f6\u30bc\u30da\u30fb\u30c1\u30f5\u30d2\u30ff\u30cb\u30af\u30ec\u30ab\u30cb\u30e9\u30e5\u30a0\u30a8\u30e9\u30bb\u30b8\u30ca\u30f0\u30d1\u30ed\u30ca\n00000 \u30ee\u30a7\u30bf\u30e8\u30a0\u30b0\u30b4\u30e3\u30fa\u30d1\u30a6\u30ad\u30b8\u30db\u30be\u30c0\u30fc\u30d1\u30ef\u30ba\u30c1\u30d5\u30e5\u30e7\u30a7\u30b5\u30b9\u30fe\u30da\u30da\u30bc\u30eb\n00000 \u554a\u9be1\u879f\u9160\u665c\u5b15\u9945\u923f\u5c9a\u52c2\u620d\u4f86\u9855\u61a0\u5960\u828d\u69a0\u800d\u69ac\u592a\u95f3\u5a80\u8ef3\u5ad4\u85c7\u56a6\u74a8\u6563\u5be0\u5206\u84ea\u879b\n00000 \u8334\u5932\u909b\u5d78\u8a60\u4e67\u904e\u4ee7\u7a85\u60f8\u61f8\u7a76\u6631\u583f\u7317\u6a66\u7881\u7e3a\u4f45\u755e\u789c\u912b\u4fe9\u6f5a\u7f47\u7db0\u8378\u66db\u80d0\u8480\u829c\u994e\n00000 \u7067\u50d5\u8600\u9d10\u668d\u9805\u7e05\u7bf8\u711c\u57fe\u5ba7\u8757\u9fc9\u4e6a\u91a9\u9c06\u50e7\u8945\u6b79\u73db\u636b\u91e7\u8cc4\u9982\u7a69\u7958\u8653\u680f\u8d22\u679c\u774a\u82a7\n00000 \uc586\ube96\uadc4\ud1b9\ucb45\uc463\ucc30\uae43\ub922\ud140\ud6be\uccae\uc8cf\uc629\ucdba\ud1c4\uc171\ud167\ubcfe\uc9e3\uadad\ud512\ud77d\uc8aa\ucbcf\ub4d6\ud5d5\ud672\ub261\ub475\ud627\ucbe3\n00000 \u0977\u090f\u097c\u090e\u096f\u090f\u0927\u0904\u097a\u097c\u0958\u096f\u092a\u0974\u0976\u0960\u090d\u097e\u092e\u0924\u0974\u0906\u097d\u0961\u091d\u0937\u0931\u0973\u0960\u0965\u0914\u0974\u0967\u0960\u096c\u0916\u0977\u0933\u0913\u0922\u0964\u096d\u096b\u0934\u0978\u0931\u091e\u0904\u0905\u0935\u096e\u092d\u0975\u0931\u0932\u0939\u0924\u0934\u096b\u090d\u095a\u096c\u096f\u0965\n00000 \u0976\u0964\u0950\u092c\u0969\u0925\u090f\u0922\u0921\u0916\u0975\u0939\u0915\u092d\u092e\u0924\u090e\u0919\u0929\u0914\u093d\u0935\u0905\u0938\u095a\u0910\u091d\u0916\u0979\u096d\u0977\u0971\u0915\u0909\u092f\u095c\u091e\u0917\u0906\u097b\u096d\u0971\u0913\u095d\u0971\u096e\u0965\u090b\u0964\u0931\u095e\u096d\u097f\u0930\u095a\u0969\u0934\u0916\u091b\u096c\u0950\u091d\u0931\u095c\n00000 YNEETLLWFJHRFRCWQOESWRTJHQQHXLWFTYWBDOGKGFBBREGEOBJXFCRBBHMHAMOX\n00000 MRJYXJENQXKMANSBYAWOKSSYLHXNWKDGCHFGKXQLHJKWYLWDSABFALDDJKBYBLFM\n00000 FOXQWXXNEACXWNSCLBLYETARFTLGMCQKRDYEQCYGXAQRHNOOWADYGTTMAGKAHXNK\n00000 \u28d3\u28d5\u288b\u2800\u28c9\u2804\u28ad\u285e\u2885\u2811\u289c\u2899\u282d\u283e\u28d6\u28b5\u284e\u2869\u285c\u28fe\u28a2\u2873\u2873\u2821\u28b8\u28a8\u2846\u28e0\u2850\u28f2\u28a9\u2854\u283b\u2884\u280c\u2879\u2857\u2855\u288f\u289b\u2808\u283e\u28e6\u283e\u2879\u2894\u283b\u28b1\u2874\u2870\u28aa\u286c\u285c\u2854\u2837\u28c6\u28fc\u28ec\u2866\u288f\u28a2\u289a\u287b\u285b\n00000 cactttgttggactatttcaagtggcgatcatctctttctgagaatctgaggttggcggagcat\n00000 TAAAACACCCAGAATCCGACCATCTATGGTCGGCACACTAAAATAATACCCTCAAAAATTGAGA<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty pistekirjoitus (&#8211;braille) satunnaislukujen raportti &#8220;kieleksi&#8221;, t\u00e4ss\u00e4 mallituloste:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --braille\n00000 \u285a\u2864\u28e4\u28d2\u286f\u28c3\u285d\u28fe\u284e\u28c2\u28ed\u2855\u28f9\u2838\u2897\u288b\u2807\u285b\u284e\u2879\u28dd\u28d1\u2805\u2830\u2875\u2811\u281d\u2819\u2897\u285e\u2864\u28ce\u28c9\u286b\u287a\u2825\u28c7\u2823\u285f\u28fa\u28c3\u280a\u281e\u28b0\u285d\u280b\u2885\u285e\u2880\u28cb\u28b7\u2810\u2884\u28af\u28b0\u281b\u2833\u28e1\u283d\u288b\u2803\u288c\u28ba\u2892\n00001 \u2807\u28e4\u28cc\u289a\u28c5\u28af\u2810\u2844\u286e\u2805\u28ba\u28f8\u281b\u285e\u284b\u28cb\u28bf\u288c\u2878\u2822\u28a0\u284b\u2855\u28fc\u2800\u28be\u2849\u2806\u2857\u28cb\u2896\u281e\u288c\u28e4\u28f6\u2826\u281f\u28db\u2829\u28bc\u28cc\u289b\u2825\u2824\u286d\u2809\u2848\u289c\u2884\u2851\u28df\u282f\u2853\u28ba\u28c8\u2845\u2814\u287f\u281e\u280d\u28a9\u28b8\u28ed\u281b\n00002 \u28e5\u281a\u2853\u28b5\u288e\u2876\u2855\u2866\u28f9\u281e\u285c\u287c\u28b3\u28c6\u2847\u28ce\u286d\u28f1\u28fd\u2852\u2849\u2859\u280c\u28b2\u2844\u2872\u28f8\u28d2\u28b7\u281c\u28e7\u280a\u28ba\u282b\u289a\u2826\u2877\u2811\u28ac\u2893\u28f2\u28a7\u283c\u280f\u2843\u2870\u28c0\u28b1\u281a\u28e8\u28d3\u28cc\u28cc\u289c\u2863\u28d0\u285d\u2860\u2849\u28ce\u28c3\u28eb\u288d\u2881\n00003 \u285d\u281e\u2883\u28a1\u28ec\u28fe\u28a1\u28c1\u2808\u28d0\u2861\u2886\u2869\u28c9\u2853\u2803\u28c3\u28e1\u2864\u284a\u2895\u286f\u28fd\u280b\u28c5\u281e\u285b\u28e0\u28b0\u28cf\u280e\u28f1\u2863\u28c4\u2840\u2802\u28cf\u28f6\u2820\u289c\u28e6\u28a6\u28f8\u28f4\u280f\u28ec\u28a9\u2857\u2873\u28ec\u28ca\u2859\u2801\u281c\u2886\u2803\u2892\u28e4\u28d0\u281e\u285e\u2839\u28de\u2826\n00004 \u2877\u280e\u28a9\u280a\u284e\u2854\u2841\u2836\u289e\u2861\u28a7\u2851\u283f\u2803\u2880\u284c\u2830\u2839\u2850\u2898\u2814\u289e\u2836\u281a\u2801\u289c\u28b8\u28ec\u28cb\u28a6\u28e9\u28b1\u28ba\u2822\u28ef\u2842\u2881\u2821\u2815\u28df\u280f\u28a0\u2867\u287b\u28be\u2802\u2830\u286b\u2858\u28a6\u288d\u2828\u28b0\u283d\u2851\u289d\u2829\u281b\u2895\u287e\u2870\u28d5\u28ea\u28e9\n00005 \u28bb\u28de\u286f\u28ab\u28b9\u2833\u2817\u285a\u28bb\u2892\u28ea\u285e\u2891\u28c0\u2859\u2800\u287a\u286f\u2865\u28ef\u280a\u28ed\u288b\u283c\u2807\u285d\u28bf\u28c0\u2862\u285e\u2889\u28ab\u2828\u2895\u2895\u2833\u28f6\u2865\u2819\u2810\u2810\u286d\u284e\u28dc\u28ed\u2806\u284b\u28e4\u2855\u2868\u286e\u2819\u28f7\u28a7\u285e\u281b\u285d\u28a4\u2892\u280a\u2889\u28e1\u2817\u2867\n00006 \u28c0\u28da\u284c\u284c\u28ab\u28ce\u28ad\u28b0\u28ff\u28e0\u2856\u28ef\u2896\u289e\u287f\u283c\u2898\u281a\u282b\u280f\u28ba\u282f\u280c\u2816\u2820\u28e5\u2813\u280b\u2813\u282b\u286e\u28f1\u2859\u287b\u28f4\u2830\u283a\u28fa\u28d9\u2895\u289e\u281b\u28d7\u2818\u287b\u2851\u281b\u289b\u280e\u28cb\u288c\u2863\u2819\u28ae\u2812\u28be\u2862\u28b8\u282d\u2808\u2819\u2858\u285a\u28bd\n00007 \u28dc\u28c7\u28ba\u28e8\u286e\u285e\u2867\u28b0\u28f2\u2851\u28b5\u2855\u2844\u281c\u2834\u28ce\u2842\u28b7\u2855\u2893\u28e4\u2865\u2820\u2849\u28fc\u283c\u28d7\u28a5\u2868\u280f\u28d5\u282f\u28f0\u28d9\u287e\u2817\u286c\u2850\u2888\u2813\u28b3\u283b\u287a\u28a9\u283a\u28fc\u28af\u2810\u28e0\u28b0\u2846\u280d\u28cf\u28cc\u2895\u2809\u2856\u28f8\u2857\u2804\u284c\u2894\u2897\u2840\n00008 \u28d3\u28aa\u28d9\u2814\u28e3\u2866\u280a\u2896\u28aa\u288c\u28cd\u2836\u2891\u2857\u285f\u2814\u284a\u2856\u2892\u285a\u28dc\u2827\u28e7\u281a\u28d5\u28a9\u28c0\u28da\u2825\u288e\u28aa\u28ab\u2899\u2849\u282c\u28e4\u282f\u2852\u2849\u281d\u28a0\u2845\u28f7\u28a0\u28ec\u2841\u2802\u283c\u2895\u28ea\u2895\u284d\u28f8\u285e\u2868\u28bc\u2819\u286a\u28f3\u2884\u28b1\u286b\u28aa\u2897\n00009 \u284c\u28df\u2820\u2875\u285b\u280d\u28d9\u2864\u287b\u283d\u2888\u2897\u2884\u28af\u28d2\u28b3\u2818\u28ba\u28f8\u281a\u2818\u288d\u281c\u288a\u28ff\u2885\u2897\u2840\u28a9\u2836\u2834\u2870\u280e\u2841\u287d\u28e6\u2889\u28cd\u283d\u287f\u28f2\u281e\u28a9\u2824\u281c\u284c\u28b0\u28d2\u28ac\u28b9\u28a8\u28ed\u28c6\u28a0\u283d\u28bf\u2844\u280a\u28f3\u284e\u2808\u28fa\u2872\u28fa\n$<\/code><\/pre>\n\n\n\n<p>Ja koodi braillen tulostamiseen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n      } else if(!strcmp(\"--braille\", argv&#91;c])) { \/\/ Braille alphabet\n\tdigits = \/\/ 0x2800 - 0x2900\n\t  \"\u2800\u2801\u2802\u2803\u2804\u2805\u2806\u2807\u2808\u2809\u280a\u280b\u280c\u280d\u280e\u280f\u2810\u2811\u2812\u2813\u2814\u2815\u2816\u2817\u2818\u2819\u281a\u281b\u281c\u281d\u281e\u281f\u2820\u2821\u2822\u2823\u2824\u2825\u2826\u2827\u2828\u2829\u282a\u282b\u282c\u282d\u282e\u282f\u2830\u2831\u2832\u2833\u2834\u2835\u2836\u2837\u2838\u2839\u283a\u283b\u283c\u283d\u283e\u283f\"\n\t  \"\u2840\u2841\u2842\u2843\u2844\u2845\u2846\u2847\u2848\u2849\u284a\u284b\u284c\u284d\u284e\u284f\u2850\u2851\u2852\u2853\u2854\u2855\u2856\u2857\u2858\u2859\u285a\u285b\u285c\u285d\u285e\u285f\u2860\u2861\u2862\u2863\u2864\u2865\u2866\u2867\u2868\u2869\u286a\u286b\u286c\u286d\u286e\u286f\u2870\u2871\u2872\u2873\u2874\u2875\u2876\u2877\u2878\u2879\u287a\u287b\u287c\u287d\u287e\u287f\"\n\t  \"\u2880\u2881\u2882\u2883\u2884\u2885\u2886\u2887\u2888\u2889\u288a\u288b\u288c\u288d\u288e\u288f\u2890\u2891\u2892\u2893\u2894\u2895\u2896\u2897\u2898\u2899\u289a\u289b\u289c\u289d\u289e\u289f\u28a0\u28a1\u28a2\u28a3\u28a4\u28a5\u28a6\u28a7\u28a8\u28a9\u28aa\u28ab\u28ac\u28ad\u28ae\u28af\u28b0\u28b1\u28b2\u28b3\u28b4\u28b5\u28b6\u28b7\u28b8\u28b9\u28ba\u28bb\u28bc\u28bd\u28be\u28bf\"\n\t  \"\u28c0\u28c1\u28c2\u28c3\u28c4\u28c5\u28c6\u28c7\u28c8\u28c9\u28ca\u28cb\u28cc\u28cd\u28ce\u28cf\u28d0\u28d1\u28d2\u28d3\u28d4\u28d5\u28d6\u28d7\u28d8\u28d9\u28da\u28db\u28dc\u28dd\u28de\u28df\u28e0\u28e1\u28e2\u28e3\u28e4\u28e5\u28e6\u28e7\u28e8\u28e9\u28ea\u28eb\u28ec\u28ed\u28ee\u28ef\u28f0\u28f1\u28f2\u28f3\u28f4\u28f5\u28f6\u28f7\u28f8\u28f9\u28fa\u28fb\u28fc\u28fd\u28fe\u28ff\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n...<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty newressu:un uusi komentorivikytkin &#8211;utf8, joka tulostaa listan utf8 merkeist\u00e4, lista on seuraavanlainen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      ----------------111111111111111122222222222222223333333333333333\n      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n      ================================================================\n    0 --- control characters ---       !\"#$%&amp;'()*+,-.\/0123456789:;&lt;=&gt;?\n   40 @ABCDEFGHIJKLMNOPQRSTUVWXYZ&#91;\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n   80 --- utf8 characters ---         --- utf8 characters ---         \n   c0 --- utf8 characters ---         --- utf8 characters ---         \n  100 \u0100\u0101\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115\u0116\u0117\u0118\u0119\u011a\u011b\u011c\u011d\u011e\u011f\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127\u0128\u0129\u012a\u012b\u012c\u012d\u012e\u012f\u0130\u0131\u0132\u0133\u0134\u0135\u0136\u0137\u0138\u0139\u013a\u013b\u013c\u013d\u013e\u013f\n  140 \u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147\u0148\u0149\u014a\u014b\u014c\u014d\u014e\u014f\u0150\u0151\u0152\u0153\u0154\u0155\u0156\u0157\u0158\u0159\u015a\u015b\u015c\u015d\u015e\u015f\u0160\u0161\u0162\u0163\u0164\u0165\u0166\u0167\u0168\u0169\u016a\u016b\u016c\u016d\u016e\u016f\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0178\u0179\u017a\u017b\u017c\u017d\u017e\u017f\n  180 \u0180\u0181\u0182\u0183\u0184\u0185\u0186\u0187\u0188\u0189\u018a\u018b\u018c\u018d\u018e\u018f\u0190\u0191\u0192\u0193\u0194\u0195\u0196\u0197\u0198\u0199\u019a\u019b\u019c\u019d\u019e\u019f\u01a0\u01a1\u01a2\u01a3\u01a4\u01a5\u01a6\u01a7\u01a8\u01a9\u01aa\u01ab\u01ac\u01ad\u01ae\u01af\u01b0\u01b1\u01b2\u01b3\u01b4\u01b5\u01b6\u01b7\u01b8\u01b9\u01ba\u01bb\u01bc\u01bd\u01be\u01bf\n  1c0 \u01c0\u01c1\u01c2\u01c3\u01c4\u01c5\u01c6\u01c7\u01c8\u01c9\u01ca\u01cb\u01cc\u01cd\u01ce\u01cf\u01d0\u01d1\u01d2\u01d3\u01d4\u01d5\u01d6\u01d7\u01d8\u01d9\u01da\u01db\u01dc\u01dd\u01de\u01df\u01e0\u01e1\u01e2\u01e3\u01e4\u01e5\u01e6\u01e7\u01e8\u01e9\u01ea\u01eb\u01ec\u01ed\u01ee\u01ef\u01f0\u01f1\u01f2\u01f3\u01f4\u01f5\u01f6\u01f7\u01f8\u01f9\u01fa\u01fb\u01fc\u01fd\u01fe\u01ff\n  200 \u0200\u0201\u0202\u0203\u0204\u0205\u0206\u0207\u0208\u0209\u020a\u020b\u020c\u020d\u020e\u020f\u0210\u0211\u0212\u0213\u0214\u0215\u0216\u0217\u0218\u0219\u021a\u021b\u021c\u021d\u021e\u021f\u0220\u0221\u0222\u0223\u0224\u0225\u0226\u0227\u0228\u0229\u022a\u022b\u022c\u022d\u022e\u022f\u0230\u0231\u0232\u0233\u0234\u0235\u0236\u0237\u0238\u0239\u023a\u023b\u023c\u023d\u023e\u023f\n  240 \u0240\u0241\u0242\u0243\u0244\u0245\u0246\u0247\u0248\u0249\u024a\u024b\u024c\u024d\u024e\u024f\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f\n  280 \u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u02ae\u02af\u02b0\u02b1\u02b2\u02b3\u02b4\u02b5\u02b6\u02b7\u02b8\u02b9\u02ba\u02bb\u02bc\u02bd\u02be\u02bf\n  2c0 \u02c0\u02c1\u02c2\u02c3\u02c4\u02c5\u02c6\u02c7\u02c8\u02c9\u02ca\u02cb\u02cc\u02cd\u02ce\u02cf\u02d0\u02d1\u02d2\u02d3\u02d4\u02d5\u02d6\u02d7\u02d8\u02d9\u02da\u02db\u02dc\u02dd\u02de\u02df\u02e0\u02e1\u02e2\u02e3\u02e4\u02e5\u02e6\u02e7\u02e8\u02e9\u02ea\u02eb\u02ec\u02ed\u02ee\u02ef\u02f0\u02f1\u02f2\u02f3\u02f4\u02f5\u02f6\u02f7\u02f8\u02f9\u02fa\u02fb\u02fc\u02fd\u02fe\u02ff\n  300 \u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\n  340 \u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u0370\u0371\u0372\u0373\u0374\u0375\u0376\u0377\u0378\u0379\u037a\u037b\u037c\u037d\u037e\u037f\n  380 \u0380\u0381\u0382\u0383\u0384\u0385\u0386\u0387\u0388\u0389\u038a\u038b\u038c\u038d\u038e\u038f\u0390\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a2\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\n  3c0 \u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\u03cf\u03d0\u03d1\u03d2\u03d3\u03d4\u03d5\u03d6\u03d7\u03d8\u03d9\u03da\u03db\u03dc\u03dd\u03de\u03df\u03e0\u03e1\u03e2\u03e3\u03e4\u03e5\u03e6\u03e7\u03e8\u03e9\u03ea\u03eb\u03ec\u03ed\u03ee\u03ef\u03f0\u03f1\u03f2\u03f3\u03f4\u03f5\u03f6\u03f7\u03f8\u03f9\u03fa\u03fb\u03fc\u03fd\u03fe\u03ff\n  400 \u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\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\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\n  440 \u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f\u0460\u0461\u0462\u0463\u0464\u0465\u0466\u0467\u0468\u0469\u046a\u046b\u046c\u046d\u046e\u046f\u0470\u0471\u0472\u0473\u0474\u0475\u0476\u0477\u0478\u0479\u047a\u047b\u047c\u047d\u047e\u047f\n  480 \u0480\u0481\u0482\u0483\u0484\u0485\u0486\u0487\u0488\u0489\u048a\u048b\u048c\u048d\u048e\u048f\u0490\u0491\u0492\u0493\u0494\u0495\u0496\u0497\u0498\u0499\u049a\u049b\u049c\u049d\u049e\u049f\u04a0\u04a1\u04a2\u04a3\u04a4\u04a5\u04a6\u04a7\u04a8\u04a9\u04aa\u04ab\u04ac\u04ad\u04ae\u04af\u04b0\u04b1\u04b2\u04b3\u04b4\u04b5\u04b6\u04b7\u04b8\u04b9\u04ba\u04bb\u04bc\u04bd\u04be\u04bf\n  4c0 \u04c0\u04c1\u04c2\u04c3\u04c4\u04c5\u04c6\u04c7\u04c8\u04c9\u04ca\u04cb\u04cc\u04cd\u04ce\u04cf\u04d0\u04d1\u04d2\u04d3\u04d4\u04d5\u04d6\u04d7\u04d8\u04d9\u04da\u04db\u04dc\u04dd\u04de\u04df\u04e0\u04e1\u04e2\u04e3\u04e4\u04e5\u04e6\u04e7\u04e8\u04e9\u04ea\u04eb\u04ec\u04ed\u04ee\u04ef\u04f0\u04f1\u04f2\u04f3\u04f4\u04f5\u04f6\u04f7\u04f8\u04f9\u04fa\u04fb\u04fc\u04fd\u04fe\u04ff\n  500 \u0500\u0501\u0502\u0503\u0504\u0505\u0506\u0507\u0508\u0509\u050a\u050b\u050c\u050d\u050e\u050f\u0510\u0511\u0512\u0513\u0514\u0515\u0516\u0517\u0518\u0519\u051a\u051b\u051c\u051d\u051e\u051f\u0520\u0521\u0522\u0523\u0524\u0525\u0526\u0527\u0528\u0529\u052a\u052b\u052c\u052d\u052e\u052f\u0530\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\n  540 \u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u0557\u0558\u0559\u055a\u055b\u055c\u055d\u055e\u055f\u0560\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\n<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 koodi, joka tulostaa edellisen listan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef DEBUG59\n\n  if(utf8) {\n    fprintf(stdout,\"%5s \",\"\");\n    fprintf(stdout,\"----------------\");\n    fprintf(stdout,\"1111111111111111\");\n    fprintf(stdout,\"2222222222222222\");\n    fprintf(stdout,\"3333333333333333\");\n    fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%5s \",\"\");\n    fprintf(stdout,\"0123456789abcdef\");\n    fprintf(stdout,\"0123456789abcdef\");\n    fprintf(stdout,\"0123456789abcdef\");\n    fprintf(stdout,\"0123456789abcdef\");\n    fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%5s \",\"\");\n    fprintf(stdout,\"================\");\n    fprintf(stdout,\"================\");\n    fprintf(stdout,\"================\");\n    fprintf(stdout,\"================\");\n    fprintf(stdout,\"\\n\");\n\n    int utf8output = 0;\n    for(c = 0; c &lt; 65535*4; c++) { \/\/ skip control chars\n      \/\/for(c = 0x2800; c &lt; 0x2900; c++) { \/\/ braille\n      unsigned char buffer10&#91;10];\n      if(c % 64 == 0) {\n\tif(c &gt; 0) {\n\t  fprintf(stdout,\"\\n\");\n\t  utf8output = 0;\n\t}\n\tfprintf(stdout,\"%5x \",c);\n\tutf8output = 1; \n     }\n      if(c &gt;= 0 &amp;&amp; c &lt; 32) {\n\tc += 31;\n\tfprintf(stdout, \"--- control characters ---      \");\n\tutf8output = 1;\n      } else if(c &gt;= 128 &amp;&amp; c &lt; 256) {\n\tc += 31;\n\tfprintf(stdout, \"--- utf8 characters ---         \");\n\tutf8output = 1;\n      } else {\n\tcodetoutf8(buffer10, c);\n\tfprintf(stdout,\"%s\",buffer10);\n\tutf8output = 1;\n      }\n    }\n    if(utf8output)\n      fprintf(stdout,\"\\n\");\n    fflush(stdout);\n    return(0);\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Koodaamisen lis\u00e4ksi tutkin ressun tuottamaa satunnaisuutta parilla ohjelmalla (koodasin ne tietysti my\u00f6s). T\u00e4ss\u00e4 ensimm\u00e4inen: Ennen se nimi oli cstat, uusi nimi on newressutest7.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;limits.h&gt;\n#include &lt;math.h&gt;\n\nstatic unsigned char *procname;\nstatic unsigned char *programname = \"cstat\/newressutest7 version 0.4 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2022-2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, first;\n  int verbose = 0, help = 0, all = 1, ctrl = 1, chars = 1,\n    cdiff = 1, cstats = 1, multiple1 = 1, m1expect = 1,\n    m1diff = 1, multiple2 = 1, m2expect = 1, m2diff = 1,\n    m2dist = 1, monobit = 1, poker2 = 1;\n  char filename&#91;128] = \"-\"; \/\/ default stdin\n  \n  FILE *fp1;\n  \n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(!strcmp(\"-\",argv&#91;c])) { \/\/ filename - --&gt;stdin\n      strncpy(filename, argv&#91;c], sizeof(filename));\n      fp1 = stdin;\n\n    } else if(strncmp(\"-\", argv&#91;c], 1)) { \/\/ filename\n      strncpy(filename, argv&#91;c], sizeof(filename));\n\n    } else if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tverbose = 1;\n\n      } else if(!strcmp(\"--help\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--all\", argv&#91;c])) {\n\n\tall = !all;\n\n\tctrl = all;\n\tchars = all;\n\tcdiff = all;\n\tcstats = all;\n\tmultiple1 = all;\n\tm1expect = all;\n\tm1diff = all;\n\tmultiple2 = all;\n\tm2expect = all;\n\tm2diff = all;\n\tm2dist = all;\n\tmonobit = all;\n\tpoker2 = all;\n\n      } else if(!strcmp(\"--ctrl\", argv&#91;c])) {\n\tctrl = !ctrl;\n\n      } else if(!strcmp(\"--chars\", argv&#91;c])) {\n\tchars = !chars;\n\n      } else if(!strcmp(\"--cdiff\", argv&#91;c])) {\n\tcdiff = !cdiff;\n\n      } else if(!strcmp(\"--cstats\", argv&#91;c])) {\n\tcstats = !cstats;\n\n      } else if(!strcmp(\"--m1\", argv&#91;c])) {\n\tmultiple1 = !multiple1;\n\tm1expect = !m1expect;\n\tm1diff = !m1diff;\n\n      } else if(!strcmp(\"--multiple1\", argv&#91;c])) {\n\tmultiple1 = !multiple1;\n\t\n      } else if(!strcmp(\"--m1expect\", argv&#91;c])) {\n\tm1expect = !m1expect;\n\n      } else if(!strcmp(\"--m1diff\", argv&#91;c])) {\n\tm1diff = !m1diff;\n\n      } else if(!strcmp(\"--m2\", argv&#91;c])) {\n\tmultiple2 = !multiple2;\n\tm2expect = !m2expect;\n\tm2diff = !m2diff;\n\tm2dist = !m2dist;\n\n      } else if(!strcmp(\"--multiple2\", argv&#91;c])) {\n\tmultiple2 = !multiple2;\n\n      } else if(!strcmp(\"--m2expect\", argv&#91;c])) {\n\tm2expect = !m2expect;\n\n      } else if(!strcmp(\"--m2diff\", argv&#91;c])) {\n\tm2diff = !m2diff;\n\n      } else if(!strcmp(\"--m2dist\", argv&#91;c])) {\n\tm2dist = !m2dist;\n\n      } else if(!strcmp(\"--monobit\", argv&#91;c])) {\n\tmonobit = !monobit;\n\n      } else if(!strcmp(\"--poker2\", argv&#91;c])) {\n\tpoker2 = !poker2;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\",procname,argv&#91;c]);\n\thelp = 1;\n\n      }\n    }\n  } \/\/ end of for(c = 1; c &lt; argc; c++)\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\",procname);\n    fprintf(stderr,\" &#91;-]\");\n    fprintf(stderr,\"\/&#91;filename]\");\n    fprintf(stderr,\" &#91;--verbose]\");\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--all]\");\n    fprintf(stderr,\" &#91;--ctrl]\");\n    fprintf(stderr,\" &#91;--chars]\");\n    fprintf(stderr,\" &#91;--cdiff]\");\n    fprintf(stderr,\" &#91;--cstats]\");\n    fprintf(stderr,\" &#91;--multiple1]\");\n    fprintf(stderr,\" &#91;--m1expect]\");\n    fprintf(stderr,\" &#91;--m1diff]\");\n    fprintf(stderr,\" &#91;--multiple2]\");\n    fprintf(stderr,\" &#91;--m2expect]\");\n    fprintf(stderr,\" &#91;--m2diff]\");\n    fprintf(stderr,\" &#91;--monobit]\");\n    fprintf(stderr,\" &#91;--poker2]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  \/\/ open needed random file\n  \n  if(!strcmp(filename, \"-\")) {\n    fp1 = stdin;\n  } else if((fp1 = fopen(filename, \"r\")) == NULL) {\n    fprintf(stderr,\"%s: fopen: cannot open file %s\", procname, filename);\n    exit(2);\n  }\n  \n#define MAXCOUNT 256\n\n  long int charcounts&#91;MAXCOUNT];\n  \n  for(c = 0; c &lt; MAXCOUNT; c++)\n    charcounts&#91;c] = 0;\n  \n#define MAX 1024\n  \n  int currentchar = 0;\n  unsigned char prevchars&#91;MAX];\n  unsigned long int m1counts&#91;MAX];\n  unsigned long int m2counts&#91;MAX];\n  \n  for(c = 0; c &lt; MAX; c++) {\n    prevchars&#91;c] = 0;\n    m1counts&#91;c] = 0;\n    m2counts&#91;c] = 0;    \n  }\n\n  unsigned long int singles = 0;\n\n  int ch, lastch, prevch;\n  unsigned long m2length;\n  \n  first = 1;\n\n  \/\/ read input file and calculate\n  \/\/ statistics\n\n  while((ch = fgetc(fp1)) != EOF) {\n\n    if(verbose) {\n      fputc(ch, stdout);\n    }\n\n    lastch = ch;\n    \n    \/\/ calculate character counts for\n    \/\/ character statistics\n    \n    charcounts&#91;ch]++;\n\n    if(ch &lt;= 0x20) \/\/ ctrl or space, skip\n      continue;\n\n    \/\/ calculate m1 multiple\n    \/\/ counts\n    \n    prevchars&#91;currentchar] = ch;\n    \n    for(c = 0; c &lt; MAX; c++) {\n\n      d = currentchar - c;\n      if(d &lt; 0)\n\td += MAX;\n\n      if(ch != prevchars&#91;d])\n\tbreak;\n\n      m1counts&#91;c]++;\n    }\n\n    if(++currentchar &gt;= MAX)\n      currentchar -= MAX;\n\n    \/\/ calculate m2 multiple\n    \/\/ counts\n    \n    if(first) {\n      prevch = ch;\n      m2length = 1;\n      first = 0;\n    } else {\n      if(prevch == ch) {\n\tm2length++;\n      } else {\n\tprevch = ch;\n\tm2counts&#91;m2length - 1]++;\n\tm2length = 1;\n      }\n    }\n    \n    singles++;\n\n  } \/\/ end of while((ch = fgetc(fp1)) != EOF)\n\n  if(singles &gt; 0)\n    m2counts&#91;m2length - 1]++; \/\/ add last m2 multiple\n\n  if(lastch != '\\n') \/\/ last char not lf, print lf\n    fputc('\\n', stdout);\n\n  fflush(stdout);\n  \n  if(singles == 0) {\n    fprintf(stderr,\"%s: no data\\n\", procname);\n    exit(2);\n  }\n    \n  \/\/ print control line if needed\n  \n  if(ctrl) {\n    char *ctrlchars&#91;] = {\n      \"NUL\", \"0x01\", \"0x02\", \"0x03\", \"0x04\", \"0x05\", \"0x06\", \"BEL\", \"BS\",\n      \"0x09\", \"LF\", \"0x0b\", \"0x0c\", \"CR\", \"0x0e\", \"0x0f\",\n      \"0x10\", \"0x11\", \"0x12\", \"0x13\", \"0x14\", \"0x15\", \"0x16\", \"0x17\", \"0x18\",\n      \"0x19\", \"0x1a\", \"ESC\", \"0x1c\", \"0x1d\", \"0x1e\", \"0x1f\",\n      \"space\"\n    };\n    \n    fprintf(stdout,\"ctrl      \");\n    first = 1;\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &gt; 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%s\", ctrlchars&#91;c]);\n\t\n\tfprintf(stdout,\":%lu\", charcounts&#91;c]);\n\t\n\tfirst = 0;\n      } \/\/ end of if(charcounts&#91;c] &gt; 0)\n    }\n    fprintf(stdout, \"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(ctrl)\n\n  \/\/ print character counts if needed\n  \n  long int min, max;\n  long int total;\n  \n  if(chars) {\n\n    min = LONG_MAX;\n    max = LONG_MIN;\n    total = 0;\n    \n    fprintf(stdout,\"chars     \");\n    first = 1;\n\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &lt;= 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%02x\", c);\n\n\tlong int temp = charcounts&#91;c];\n\t\n\tfprintf(stdout,\":%lu\", temp);\n\t\n\ttotal += temp;\n\n\tif(min &gt; temp)\n\t  min = temp;\n\tif(max &lt; temp)\n\t  max = temp;\n\n\tfirst = 0;\n      }\n    }\n    fprintf(stdout,\", total:%ld\", total);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(chars)\n\n  \/\/ calculate character statistics\n\n  unsigned long int ctotal = 0, count = 0, average = 0,\n    characters = 0, utf8first = 0, utf8other = 0,\n    asciicnt = 0, ctrlcnt = 0;\n\n  first = 1;\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    if(charcounts&#91;c] &gt; 0) {\n  \n      if(c &lt; 0x20) { \/\/ ctrl, count &amp; skip\n\tctrlcnt += charcounts&#91;c];\n\tcontinue;\n      }\n\n      if(c &lt; 0x80)\n\tasciicnt += charcounts&#91;c];\n      \n      if(c == 0x20) \/\/ space, skip\n\tcontinue;\n\n      ctotal += charcounts&#91;c];\n      count++;\n      \n      if(c &lt; 0x80 || c &gt; 0xbf) \/\/ ascii or utf8 first char\n\tcharacters += charcounts&#91;c];\n\n      if(c &gt; 0xbf) \/\/ utf8 first char\n\tutf8first += charcounts&#91;c];\n\n      if(c &gt;= 0x80 &amp;&amp; c &lt;= 0xbf) \/\/ utf8 other char\n\tutf8other += charcounts&#91;c];\n\n    } \/\/ if(charcounts&#91;c] &gt; 0)\n  } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n\n  double entropy = 0;\n\n  \/\/ calculate entropy\n  \n  for(c = 0; c &lt; MAXCOUNT; c++) {\n\n    if(c &lt;= 0x20) \/\/ ctrl or space, skip\n      continue;\n\n    if(charcounts&#91;c] &gt; 0)\n      entropy += (double)charcounts&#91;c] \/ ctotal * log2((double) charcounts&#91;c] \/ ctotal);\n\n  }\n  if(entropy &lt; 0)\n    entropy = -entropy;\n\n  \/\/ calculate average\n  \n  average = ctotal \/ count;\n\n  \/\/ calculate character differences\n  \n  if(cdiff) {\n    fprintf(stdout,\"cdiff     \");\n\n    min = LONG_MAX;\n    max = LONG_MIN;\n    long int total = 0;\n    \n    first = 1;\n\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n\n      if(c &lt;= 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%02x\", c);\n\n\tlong int temp;\n\ttemp = average - charcounts&#91;c];\n\n\tfprintf(stdout,\":%ld\", temp);\n\n\ttotal += temp;\n\n\tif(min &gt; temp)\n\t  min = temp;\n\tif(max &lt; temp)\n\t  max = temp;\n\n\tfirst = 0;\n      } \/\/ end of if(charcounts&#91;c] &gt; 0)\n    } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n    \n    fprintf(stdout,\", total:%ld\", total);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(cdiff)\n  \n  \/\/ print character statistics\n  \n  if(cstats) {\n    fprintf(stdout,\"cstats    \");\n\n    fprintf(stdout,\"total:%lu\", ctotal);\n    fprintf(stdout,\", count:%lu\", count);\n    \n    if((double)ctotal \/ count != ctotal \/ count)\n      fprintf(stdout,\", average:%f\", (double)ctotal \/ count);\n    else\n      fprintf(stdout,\", average:%ld\", ctotal \/ count);\n    \n    fprintf(stdout,\", characters:%lu\", characters);\n    fprintf(stdout,\", utf8first:%lu\", utf8first);\n    fprintf(stdout,\", utf8other:%lu\", utf8other);\n    fprintf(stdout,\", ascii:%lu\", asciicnt);\n    fprintf(stdout,\", ctrl:%lu\", ctrlcnt);\n    fprintf(stdout,\", entropy:%f\", entropy);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(cstats)\n\n  \/\/ print statistics on m1 multiples\n\n  if(multiple1) {\n    fprintf(stdout,\"multiple1 \");\n\n    long int total = 0;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(m1counts&#91;c] &gt; 0) {\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\", twins\"); break;\n          case 2: fprintf(stdout,\", triplets\"); break;\n          case 3: fprintf(stdout,\", quadruplets\"); break;\n          case 4: fprintf(stdout,\", quintuplets\"); break;\n          case 5: fprintf(stdout,\", sixlets\"); break;\n          default: fprintf(stdout,\", %dlets\", c + 1); break;\n\t}\n\tfprintf(stdout,\":%lu\", m1counts&#91;c]);\n\ttotal += m1counts&#91;c];\n      }\n    }\n    fprintf(stdout,\", total:%ld\", total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(multiple1)\n  \n  \/\/ expected m1 multiple statistics\n  \n  if(m1expect) {\n    fprintf(stdout,\"m1expect  \");\n\n    long int expect;\n    long int total = 0;\n    \n    expect = singles;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(expect &gt; 0 || m1counts&#91;c] &gt; 0) {\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\", twins\"); break;\n          case 2: fprintf(stdout,\", triplets\"); break;\n          case 3: fprintf(stdout,\", quadruplets\"); break;\n          case 4: fprintf(stdout,\", quintuplets\"); break;\n          case 5: fprintf(stdout,\", sixlets\"); break;\n          default: fprintf(stdout,\", %dlets\", c + 1); break;\n\t}\n\tfprintf(stdout,\":%lu\", expect);\n\ttotal += expect;\n      }\n\n      if(count == 1)\n\tbreak;\n      \n      expect \/= count;\n    }\n    fprintf(stdout,\", total:%ld\", total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(m1expect)\n\n  \/\/ difference between statistics and\n  \/\/ real m1 counts\n\n  if(m1diff) {\n  \n    fprintf(stdout,\"m1diff    \");\n\n    min = LONG_MAX;\n    max = LONG_MIN;\n    long int expect;\n    long int diffall = 0;\n    \n    expect = singles;\n     \n    for(c = 0; c &lt; MAX; c++) {\n      if(expect &gt; 0 || m1counts&#91;c] &gt; 0) {\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\", twins\"); break;\n          case 2: fprintf(stdout,\", triplets\"); break;\n          case 3: fprintf(stdout,\", quadruplets\"); break;\n          case 4: fprintf(stdout,\", quintuplets\"); break;\n          case 5: fprintf(stdout,\", sixlets\"); break;\n          default: fprintf(stdout,\", %dlets\", c + 1); break;\n\t}\n\tlong int temp = expect - m1counts&#91;c];\n\tfprintf(stdout,\":%ld\", temp);\n\tdiffall += temp;\n\tif(min &gt; temp)\n\t  min = temp;\n\tif(max &lt; temp)\n\t  max = temp;\n\texpect \/= count;\n      }\n      if(count == 1)\n\tbreak;\n    }\n    fprintf(stdout,\", total:%ld\", diffall);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ if(m1diff)\n\n  \/\/ print statistics on m2 multiples\n  \n  if(multiple2) {\n    fprintf(stdout, \"multiple2 \");\n\n    unsigned long int total = 0;\n    \n    first = 1;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(m2counts&#91;c] &gt; 0) {\n\tif(first == 0)\n\t  fprintf(stdout,\", \");\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\"twins\"); break;\n          case 2: fprintf(stdout,\"triplets\"); break;\n          case 3: fprintf(stdout,\"quadruplets\"); break;\n          case 4: fprintf(stdout,\"quintuplets\"); break;\n          case 5: fprintf(stdout,\"sixlets\"); break;\n          default: fprintf(stdout,\"%dlets\", c + 1); break;\n\t}\n\tfprintf(stdout,\":%lu\", m2counts&#91;c]);\n\ttotal += m2counts&#91;c] * (c + 1);\n\tfirst = 0;\n      }\n    } \/\/ end of for(c = 1; c &lt; MAX; c++)\n    \n    fprintf(stdout,\", total:%lu\",total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(multiple2)\n\n  unsigned long int m2expects&#91;MAX];\n  double base;\n  \n  for(c = 0; c &lt; MAX; c++) {\n    m2expects&#91;c] = 0;\n  }\n    \n  base = (((double)count - 1) \/ count)  * (((double)count - 1) \/ count);\n  for(c = 0; c &lt; MAX; c++) {\n    if(base * ctotal &gt; 0) {\n      m2expects&#91;c] = (unsigned long int) (base * ctotal);\n      base *= ((double)1 \/ count);\n    }\n  }\n\n  \/\/ expected m2 multiple statistics\n\n  if(m2expect) {\n    fprintf(stdout,\"m2expect  \");\n\n    long int expectall = 0;\n    \n    first = 1;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(m2counts&#91;c]&gt; 0 || m2expects&#91;c]) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tswitch(c) {\n\t  case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\"twins\"); break;\n          case 2: fprintf(stdout,\"triplets\"); break;\n          case 3: fprintf(stdout,\"quadruplets\"); break;\n          case 4: fprintf(stdout,\"quintuplets\"); break;\n          case 5: fprintf(stdout,\"sixlets\"); break;\n          default: fprintf(stdout,\"%dlets\", c + 1); break;\n\t}\n\tfprintf(stdout,\":%lu\", m2expects&#91;c]);\n\texpectall += m2expects&#91;c] * (c + 1);\n\tfirst = 0;\n      }\n    }\n    fprintf(stdout,\", total:%lu\", expectall);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(m2expect)\n\n  \/\/ difference between statistics and\n  \/\/ real m2 counts\n  \n  if(m2diff) {\n    fprintf(stdout,\"m2diff    \");\n\n    min = LONG_MAX;\n    max = LONG_MIN;    \n    long int diffall = 0;\n\n    first = 1;\n    \n    for(c = 0; c &lt; MAX; c++) { \n      if(m2counts&#91;c] &gt; 0 || m2expects&#91;c] &gt; 0) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\"twins\"); break;\n          case 2: fprintf(stdout,\"triplets\"); break;\n          case 3: fprintf(stdout,\"quadruplets\"); break;\n          case 4: fprintf(stdout,\"quintuplets\"); break;\n          case 5: fprintf(stdout,\"sixlets\"); break;\n          default: fprintf(stdout,\"%dlets\", c + 1); break;\n\t}\n\tlong int temp = m2expects&#91;c] - m2counts&#91;c];\n\tfprintf(stdout,\":%ld\", temp);\n\tdiffall += temp;\n\tif(min &gt; temp)\n\t  min = temp;\n\tif(max &lt; temp)\n\t  max = temp;\n\tfirst = 0;\n      }\n    }\n    fprintf(stdout,\", total:%ld\", diffall);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(m2diff)\n\n  if(m2dist) {\n    fprintf(stdout,\"m2dist    \");\n\n    unsigned long int total;\n    \n    first = 1;\n    total = 0;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(m2counts&#91;c] &gt; 0) {\n\tif(first == 0)\n\t  fprintf(stdout,\", \");\n\tswitch(c) {\n          case 0: fprintf(stdout,\"singles\"); break;\n          case 1: fprintf(stdout,\"twins\"); break;\n          case 2: fprintf(stdout,\"triplets\"); break;\n          case 3: fprintf(stdout,\"quadruplets\"); break;\n          case 4: fprintf(stdout,\"quintuplets\"); break;\n          case 5: fprintf(stdout,\"sixlets\"); break;\n          default: fprintf(stdout,\"%dlets\", c + 1); break;\n\t}\n\tfprintf(stdout,\":%lu\", ctotal \/ m2counts&#91;c]);\n\ttotal += m2counts&#91;c] * (c + 1);\n\tfirst = 0;\n      }\n    } \/\/ end of for(c = 1; c &lt; MAX; c++)\n    \n    fprintf(stdout,\", total:%lu\",total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(multiple2)\n  \n#define aDEBUG84 2\n\n  \/\/ print monobit statistics if needed\n  \n  if(monobit) {\n    unsigned long monobitzeroes = 0;\n    unsigned long monobitones = 0;\n    \n    if(count == 2 &amp;&amp; charcounts&#91;'0'] &gt; 0 &amp;&amp; charcounts&#91;'1'] &gt; 0) {\n      monobitzeroes += charcounts&#91;'0'];\n      monobitones += charcounts&#91;'1'];\n    }\n\n    int ok = 0;\n    \n    if(count == 16) {\n      unsigned char hex&#91;] = \"0123456789abcdef\";\n      ok = 1;\n      for(c = 0; c &lt; strlen(hex); c++) {\n\tif(charcounts&#91;hex&#91;c]] &lt; 1)\n\t  ok = 0;\n      }\n      if(ok) {\n\tfor(c = 0; c &lt; strlen(hex); c++) {\n#ifdef DEBUG84\n\t  fprintf(stdout,\"c:%3d\", c);\n\t  fprintf(stdout,\", count:%ld\", charcounts&#91;hex&#91;c]]);\n\t  fprintf(stdout,\", bits:\");\n\t  for(d = 3 ; d &gt;= 0; d--) {\n\t    fprintf(stdout,\"%1d\", (c &gt;&gt; d &amp; 1));\n\t  }\n#endif\n\t  for(d = 0 ; d &lt; 4; d++) {\n\t    monobitzeroes += charcounts&#91;hex&#91;c]] * !(c &gt;&gt; d &amp; 1);\n\t    monobitones += charcounts&#91;hex&#91;c]] * (c &gt;&gt; d &amp; 1);\n\t  }\n#ifdef DEBUG84\n\t  fprintf(stdout,\", zeroes:%ld\", monobitzeroes);\n\t  fprintf(stdout,\", ones:%ld\", monobitones);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t}\n      }\n    } \/\/ end of if(count == 16)\n    if(ok) {\n      fprintf(stdout,\"monobit   \");\n      fprintf(stdout,\"0:%ld\", monobitzeroes);\n      fprintf(stdout,\", 1:%ld\", monobitones);\n      fprintf(stdout,\", total:%ld\", monobitzeroes + monobitones);\n      fprintf(stdout,\"\\n\");\n    }\n    fflush(stdout);\n  } \/\/ end of if(monobit)\n\n#define aDEBUG87 2\n\n  \/\/ print poker2 statistics if needed\n  \n  if(poker2) {\n    unsigned long poker2&#91;4];\n\n    for(c = 0; c &lt; sizeof(poker2); c++)\n      poker2&#91;c] = 0;\n\n    int ok = 0;\n    \n    if(count == 16) {\n      unsigned char hex&#91;] = \"0123456789abcdef\";\n      ok = 1;\n      for(c = 0; c &lt; strlen(hex); c++) {\n\tif(charcounts&#91;hex&#91;c]] &lt; 1)\n\t  ok = 0;\n      }\n      if(ok) {\n\tfor(c = 0; c &lt; strlen(hex); c++) {\n#ifdef DEBUG87\n\t  fprintf(stdout,\"c:%3d\", c);\n\t  fprintf(stdout,\", count:%ld\", charcounts&#91;hex&#91;c]]);\n\t  fprintf(stdout,\", bits:\");\n\t  for(d = 3 ; d &gt;= 0; d--) {\n\t    fprintf(stdout,\"%1d\", (c &gt;&gt; d &amp; 1));\n\t  }\n#endif\n\t  for(d = 0 ; d &lt; 2; d++) {\n\t    poker2&#91;c &gt;&gt; (d * 2) &amp; 3] += charcounts&#91;hex&#91;c]];\n\t  }\n#ifdef DEBUG87\n\t  fprintf(stdout,\", poker2 \");\n\t  first = 1;\n\t  for(d = 0 ; d &lt; 4; d++) {\n\t    if(!first)\n\t      fprintf(stdout,\", \");\n\t    fprintf(stdout,\"%d:%ld\", d, poker2&#91;d]);\n\t    first = 0;\n\t  }\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t} \/\/ end of for(c = 0; c &lt; strlen(hex); c++)\n      } \/\/ end of if(ok)\n    } \/\/ end of if(count == 16)\n    \n    if(ok) {\n      long int total = 0;\n\n      fprintf(stdout,\"poker2    \");\n      first = 1;\n\n      for(d = 0; d &lt; 4; d++) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tfprintf(stdout,\"%d:%ld\", d, poker2&#91;d]);\n\ttotal += poker2&#91;d];\n\tfirst = 0;\n      }\n      fprintf(stdout,\", total:%ld\", total);\n      fprintf(stdout,\"\\n\");\n    } \/\/ end of if(ok)\n    fflush(stdout);\n  } \/\/ end of if(poker2)\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa ohjelman tuloste 8 merkki\u00e4 pitkille heksajonoille, joita on kahdeksan kappaletta. Tulosteelle tulostetaan 1000 rivi\u00e4: &#8220;ctrl&#8221; rivill\u00e4 on kontrollimerkkien m\u00e4\u00e4r\u00e4t t\u00e4ss\u00e4 LF (linefeed, rivinvaihto) merkkej\u00e4 on yksi jokaiselle riville eli 1000 kpl. Seuraava &#8220;chars&#8221; rivi listaa materiaalissa olleet merkit. T\u00e4ss\u00e4 merkit ovat heksaa eli merkkilaskureita on 16 kpl, nollasta viiteentoista (f). &#8220;cdiff&#8221; rivill\u00e4 on erotus keskiarvoon (4000). &#8220;cstats&#8221; rivill\u00e4 on erilaisia tilastollisia lukuja.<\/p>\n\n\n\n<p>Entropy l\u00e4henee t\u00e4ss\u00e4 nelosta, koska yhdess\u00e4 heksamerkiss\u00e4 on 4  bitti\u00e4 (1, 2, 4 ja 8). Kasvattamalla rivim\u00e4\u00e4r\u00e4\u00e4 entropy saavuttaa nelosen.<\/p>\n\n\n\n<p>&#8220;multiple1&#8221; listaa materiaalissa olevien eri pituisten monikkojen m\u00e4\u00e4r\u00e4n. &#8220;m1expect&#8221; kertoo eri monikkojen odotetun tilastollisen m\u00e4\u00e4r\u00e4n. &#8220;m1diff&#8221; kertoo edellisten erotuksen. &#8220;multiple2&#8221;, &#8220;m2expect&#8221; ja &#8220;m2diff&#8221; ovat samalla tavalla monikkojen lukum\u00e4\u00e4ri\u00e4, mutta ne eroavat siten, ett\u00e4 ykk\u00f6sluvuissa merkki voi kuulua useampaan monikkoon. Merkki (esim &#8216;2&#8217;) voi kuulua kolmosmonikkoon (esim &#8216;222&#8217;), kakkosmonikkoon (&#8217;22&#8217;) ja ykk\u00f6smonikkoon. Toisin sanoen kolmosmonikko (&#8216;222&#8217;) sis\u00e4lt\u00e4\u00e4 kolme ykk\u00f6smonikkoa (&#8216;2&#8242;) (singles), kaksi kakkosmonikkoa (&#8217;22&#8217;) (twins) ja yhden kolmosmonikon (&#8216;222&#8217;) (triplets). Kakkosvaihtoehdossa merkki voi kuulua vain yhteen monikkoon.<\/p>\n\n\n\n<p>&#8220;m1expect&#8221; ja &#8220;m2expect&#8221;, tilastolliset rivim\u00e4\u00e4r\u00e4t, l\u00e4henev\u00e4t havaittuja rivim\u00e4\u00e4ri\u00e4 &#8220;multiple1&#8221; ja &#8220;multiple2&#8221; materiaalin kasvaessa, ja osan erotuksista &#8220;diff&#8221; pit\u00e4isi olla negatiivisia ja osan positiivisia. Kaavat tilastollisille m\u00e4\u00e4rille ovat tietysti ohjelmassa, mielest\u00e4ni ne ovat aika l\u00e4hell\u00e4 oikeita.<\/p>\n\n\n\n<p>Huomaa, ett\u00e4 t\u00e4ss\u00e4 monikot voivat jatkua yli v\u00e4lily\u00f6nnin tai rivinvaihdon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single --lineno -x -s8 -w8 -l1000 | .\/cstat\nctrl      LF:1000\nchars     0:4052, 1:3863, 2:4019, 3:3964, 4:4021, 5:4007, 6:4015, 7:4119, 8:3955, 9:3877, a:3929, b:4114, c:4061, d:3987, e:4060, f:3957, total:64000\ncdiff     0:-52, 1:137, 2:-19, 3:36, 4:-21, 5:-7, 6:-15, 7:-119, 8:45, 9:123, a:71, b:-114, c:-61, d:13, e:-60, f:43\ncstats    min:3863, max:4119, total:64000, count:16, average:4000, characters:64000, utf8first:0, utf8other:0, ascii:64000, ctrl:1000, entropy:3.999767\nmultiple1 singles:64000, twins:3944, triplets:227, quadruplets:12, total:68183\nm1expect  singles:64000, twins:4000, triplets:250, quadruplets:15, total:68265\nm1diff    singles:0, twins:56, triplets:23, quadruplets:3, total:82\nmultiple2 singles:56339, twins:3502, triplets:203, quadruplets:12, total:64000\nm2expect  singles:56250, twins:3515, triplets:219, quadruplets:13, total:63989\nm2diff    singles:-89, twins:13, triplets:16, quadruplets:1, total:-59\nmonobit   0:127768, 1:128232, total:256000\npoker2    0:31987, 1:31896, 2:31898, 3:32219, total:128000<\/code><\/pre>\n\n\n\n<p>Seuraavassa ajossa satunnaislukujen v\u00e4liss\u00e4 on v\u00e4lily\u00f6ntej\u00e4 (&#8211;space),  jolloin ctrl riville tulostuu my\u00f6s v\u00e4lily\u00f6nnit. V\u00e4lily\u00f6nnit eiv\u00e4t kuitenkaan vaikuta tuloksiin: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single --lineno -x -s8 -w8 -l1000 --space| .\/cstat\nctrl      LF:1000, space:7000\nchars     0:4006, 1:3882, 2:3965, 3:3955, 4:3879, 5:4093, 6:4029, 7:3915, 8:4062, 9:4095, a:4105, b:3991, c:4023, d:4018, e:4014, f:3968, total:64000\ncdiff     0:-6, 1:118, 2:35, 3:45, 4:121, 5:-93, 6:-29, 7:85, 8:-62, 9:-95, a:-105, b:9, c:-23, d:-18, e:-14, f:32\ncstats    min:3879, max:4105, total:64000, count:16, average:4000, characters:64000, utf8first:0, utf8other:0, ascii:71000, ctrl:1000, entropy:3.999789\nmultiple1 singles:64000, twins:3953, triplets:234, quadruplets:11, total:68198\nm1expect  singles:64000, twins:4000, triplets:250, quadruplets:15, total:68265\nm1diff    singles:0, twins:47, triplets:16, quadruplets:4, total:67\nmultiple2 singles:56328, twins:3496, triplets:212, quadruplets:11, total:64000\nm2expect  singles:56250, twins:3515, triplets:219, quadruplets:13, total:63989\nm2diff    singles:-78, twins:19, triplets:7, quadruplets:2, total:-50\nmonobit   0:127926, 1:128074, total:256000\npoker2    0:31778, 1:32004, 2:32366, 3:31852, total:128000<\/code><\/pre>\n\n\n\n<p>Jos ajosta puuttuu &#8211;lineno parametri, eli rivinumero tulostetaan, rivinumero kentt\u00e4 v\u00e4\u00e4rist\u00e4\u00e4 raporttia, t\u00e4ss\u00e4 esimerkiksi suuri nollien m\u00e4\u00e4r\u00e4. Lis\u00e4ksi ctrl-riville tulevat rivinumeron ja satunnaismerkkien v\u00e4liset v\u00e4lily\u00f6nnit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/newressu --single -x -s8 -w8 -l1000| .\/cstat\nctrl      LF:1000, space:1000\nchars     0:6103, 1:4307, 2:4289, 3:4325, 4:4235, 5:4329, 6:4237, 7:4327, 8:4362, 9:4276, a:3972, b:4115, c:3985, d:4019, e:4023, f:4096, total:69000\ncdiff     0:-1791, 1:5, 2:23, 3:-13, 4:77, 5:-17, 6:75, 7:-15, 8:-50, 9:36, a:340, b:197, c:327, d:293, e:289, f:216\ncstats    min:3972, max:6103, total:69000, count:16, average:4312.500000, characters:69000, utf8first:0, utf8other:0, ascii:70000, ctrl:1000, entropy:3.991895\nmultiple1 singles:69000, twins:5364, triplets:405, quadruplets:39, quintuplets:3, total:74811\nm1expect  singles:69000, twins:4312, triplets:269, quadruplets:16, quintuplets:1, total:73598\nm1diff    singles:0, twins:-1052, triplets:-136, quadruplets:-23, quintuplets:-2, total:-1213\nmultiple2 singles:58677, twins:4593, triplets:330, quadruplets:33, quintuplets:3, total:69000\nm2expect  singles:60644, twins:3790, triplets:236, quadruplets:14, quintuplets:0, total:68988\nm2diff    singles:1967, twins:-803, triplets:-94, quadruplets:-19, quintuplets:-3, total:1048\nmonobit   0:142723, 1:133277, total:276000\npoker2    0:37709, 1:34059, 2:33246, 3:32986, total:138000<\/code><\/pre>\n\n\n\n<p>Bin\u00e4\u00e4risten satunnaislukujen (-b) tilastossa entropy (t\u00e4ss\u00e4 satunnaisbitti\u00e4 per merkki) l\u00e4henee ykkost\u00e4: Lis\u00e4ksi chars rivill\u00e4 on vain &#8216;0&#8217; ja &#8216;1&#8217; ja count = 2. Satunnaismateriaali koostuu nollista ja ykk\u00f6sist\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/newressu --single -b -s8 -w8 -l10000 --lineno | .\/cstat\nctrl      LF:10000\nchars     0:319983, 1:320017, total:640000\ncdiff     0:17, 1:-17\ncstats    min:319983, max:320017, total:640000, count:2, average:320000, characters:640000, utf8first:0, utf8other:0, ascii:640000, ctrl:10000, entropy:1.000000\nmultiple1 singles:640000, twins:319593, triplets:159651, quadruplets:79760, quintuplets:39885, sixlets:19962, 7lets:10030, 8lets:5021, 9lets:2520, 10lets:1300, 11lets:669, 12lets:340, 13lets:167, 14lets:76, 15lets:37, 16lets:14, 17lets:3, 18lets:1, total:1279029\nm1expect  singles:640000, twins:320000, triplets:160000, quadruplets:80000, quintuplets:40000, sixlets:20000, 7lets:10000, 8lets:5000, 9lets:2500, 10lets:1250, 11lets:625, 12lets:312, 13lets:156, 14lets:78, 15lets:39, 16lets:19, 17lets:9, 18lets:4, 19lets:2, 20lets:1, total:1279995\nm1diff    singles:0, twins:407, triplets:349, quadruplets:240, quintuplets:115, sixlets:38, 7lets:-30, 8lets:-21, 9lets:-20, 10lets:-50, 11lets:-44, 12lets:-28, 13lets:-11, 14lets:2, 15lets:2, 16lets:5, 17lets:6, 18lets:3, 19lets:2, 20lets:1, total:966\nmultiple2 singles:160465, twins:80051, triplets:40016, quadruplets:19952, quintuplets:9991, sixlets:4923, 7lets:2508, 8lets:1281, 9lets:589, 10lets:302, 11lets:156, 12lets:82, 13lets:52, 14lets:16, 15lets:12, 16lets:9, 17lets:1, 18lets:1, total:640000\nm2expect  singles:160000, twins:80000, triplets:40000, quadruplets:20000, quintuplets:10000, sixlets:5000, 7lets:2500, 8lets:1250, 9lets:625, 10lets:312, 11lets:156, 12lets:78, 13lets:39, 14lets:19, 15lets:9, 16lets:4, 17lets:2, 18lets:1, total:639921\nm2diff    singles:-465, twins:-51, triplets:-16, quadruplets:48, quintuplets:9, sixlets:77, 7lets:-8, 8lets:-31, 9lets:36, 10lets:10, 11lets:0, 12lets:-4, 13lets:-13, 14lets:3, 15lets:-3, 16lets:-5, 17lets:1, 18lets:0, total:-412<\/code><\/pre>\n\n\n\n<p>Oktaalisten satunnaislukujen entropy l\u00e4henee kolmosta: tietenkin chars rivill\u00e4 on numerot &#8216;0&#8217;:sta &#8216;7&#8217;:aan ja count on 8. Materiaali koostuu merkeist\u00e4 &#8216;0&#8217;:sta &#8216;7&#8217;:\u00e4\u00e4n.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -o -s8 -w8 -l1000000 --lineno | .\/cstat\nctrl      LF:1000000\nchars     0:7997975, 1:8000644, 2:7998781, 3:7998010, 4:8005153, 5:7997054, 6:8002654, 7:7999729, total:64000000\ncdiff     0:2025, 1:-644, 2:1219, 3:1990, 4:-5153, 5:2946, 6:-2654, 7:271\ncstats    min:7997054, max:8005153, total:64000000, count:8, average:8000000, characters:64000000, utf8first:0, utf8other:0, ascii:64000000, ctrl:1000000, entropy:3.000000\nmultiple1 singles:64000000, twins:7999189, triplets:998260, quadruplets:124870, quintuplets:15650, sixlets:2015, 7lets:239, 8lets:41, 9lets:8, 10lets:2, total:73140274\nm1expect  singles:64000000, twins:8000000, triplets:1000000, quadruplets:125000, quintuplets:15625, sixlets:1953, 7lets:244, 8lets:30, 9lets:3, 10lets:0, total:73142855\nm1diff    singles:0, twins:811, triplets:1740, quadruplets:130, quintuplets:-25, sixlets:-62, 7lets:5, 8lets:-11, 9lets:-5, 10lets:-2, total:2581\nmultiple2 singles:48999882, twins:6127539, triplets:764170, quadruplets:95585, quintuplets:11859, sixlets:1578, 7lets:165, 8lets:27, 9lets:4, 10lets:2, total:64000000\nm2expect  singles:49000000, twins:6125000, triplets:765625, quadruplets:95703, quintuplets:11962, sixlets:1495, 7lets:186, 8lets:23, 9lets:2, 10lets:0, total:63999971\nm2diff    singles:118, twins:-2539, triplets:1455, quadruplets:118, quintuplets:103, sixlets:-83, 7lets:21, 8lets:-4, 9lets:-2, 10lets:-2, total:-815<\/code><\/pre>\n\n\n\n<p>Desimaalilukujen entropy l\u00e4henee 3.321928:aa (desimaalimerkki koostuu biteist\u00e4 1, 2 ja 4 ja osa bitist\u00e4 8) ja chars rivin numerot ovat v\u00e4lill\u00e4 0-9: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -d -s8 -w8 -l1000000 --lineno | .\/cstat\nctrl      LF:1000000\nchars     0:6396007, 1:6400047, 2:6402915, 3:6401529, 4:6404519, 5:6397437, 6:6398466, 7:6397870, 8:6397703, 9:6403507, total:64000000\ncdiff     0:3993, 1:-47, 2:-2915, 3:-1529, 4:-4519, 5:2563, 6:1534, 7:2130, 8:2297, 9:-3507\ncstats    min:6396007, max:6404519, total:64000000, count:10, average:6400000, characters:64000000, utf8first:0, utf8other:0, ascii:64000000, ctrl:1000000, entropy:3.321928\nmultiple1 singles:64000000, twins:6404055, triplets:640874, quadruplets:64161, quintuplets:6447, sixlets:625, 7lets:54, 8lets:1, total:71116217\nm1expect  singles:64000000, twins:6400000, triplets:640000, quadruplets:64000, quintuplets:6400, sixlets:640, 7lets:64, 8lets:6, total:71111110\nm1diff    singles:0, twins:-4055, triplets:-874, quadruplets:-161, quintuplets:-47, sixlets:15, 7lets:10, 8lets:5, total:-5107\nmultiple2 singles:51832764, twins:5186468, triplets:518999, quadruplets:51892, quintuplets:5251, sixlets:518, 7lets:52, 8lets:1, total:64000000\nm2expect  singles:51840000, twins:5184000, triplets:518400, quadruplets:51840, quintuplets:5184, sixlets:518, 7lets:51, 8lets:5, total:63999985\nm2diff    singles:7236, twins:-2468, triplets:-599, quadruplets:-52, quintuplets:-67, sixlets:0, 7lets:-1, 8lets:4, total:4053<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 uudestaan heksadesimaali, jossa entropy l\u00e4henee nelosta ja chars rivill\u00e4 ja materiaalissa on heksanumerot(ita) &#8216;0&#8217; &#8211; &#8216;f&#8217;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -x -s8 -w8 -l1000000 --lineno | .\/cstat\nctrl      LF:1000000\nchars     0:4002235, 1:4000771, 2:3999619, 3:4000456, 4:3995918, 5:4000856, 6:4003044, 7:3999699, 8:3998536, 9:4000183, a:4001238, b:3998398, c:4000312, d:4001384, e:3999341, f:3998010, total:64000000\ncdiff     0:-2235, 1:-771, 2:381, 3:-456, 4:4082, 5:-856, 6:-3044, 7:301, 8:1464, 9:-183, a:-1238, b:1602, c:-312, d:-1384, e:659, f:1990\ncstats    min:3995918, max:4003044, total:64000000, count:16, average:4000000, characters:64000000, utf8first:0, utf8other:0, ascii:64000000, ctrl:1000000, entropy:4.000000\nmultiple1 singles:64000000, twins:4001492, triplets:249591, quadruplets:15572, quintuplets:959, sixlets:62, 7lets:3, total:68267679\nm1expect  singles:64000000, twins:4000000, triplets:250000, quadruplets:15625, quintuplets:976, sixlets:61, 7lets:3, total:68266665\nm1diff    singles:0, twins:-1492, triplets:409, quadruplets:53, quintuplets:17, sixlets:-1, 7lets:0, total:-1014\nmultiple2 singles:56246607, twins:3517882, triplets:219406, quadruplets:13716, quintuplets:838, sixlets:56, 7lets:3, total:64000000\nm2expect  singles:56250000, twins:3515625, triplets:219726, quadruplets:13732, quintuplets:858, sixlets:53, 7lets:3, total:63999985\nm2diff    singles:3393, twins:-2257, triplets:320, quadruplets:16, quintuplets:20, sixlets:-3, 7lets:0, total:1489\nmonobit   0:128004472, 1:127995528, total:256000000\npoker2    0:32000082, 1:32002711, 2:32001597, 3:31995610, total:128000000<\/code><\/pre>\n\n\n\n<p>cstat sis\u00e4lt\u00e4\u00e4 &#8211;help parametrin, joka kertoo komennon kirjoitusasun: cstat tulostaa komennon kirjoitusasun my\u00f6s, jos sen parametri on v\u00e4\u00e4rin kirjoitettu. Jos halutaan lukea stdin (oletus) tiedostoa, parametriksi voi laittaa pelk\u00e4n miinusmerkin (&#8216;-&#8216;). Jos parametrin edell\u00e4 ei ole miinusmerkki\u00e4, se katsotaan tiedostoksi. Vain viimeinen tiedoston nimi katsotaan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/cstat --help\n.\/cstat &#91;-]\/&#91;filename] &#91;--verbose] &#91;--help] &#91;--all] &#91;--ctrl] &#91;--chars] &#91;--cdiff] &#91;--cstats] &#91;--multiple1] &#91;--m1expect] &#91;--m1diff] &#91;--multiple2] &#91;--m2expect] &#91;--m2diff] &#91;--monobit] &#91;--poker2]<\/code><\/pre>\n\n\n\n<p>&#8211;verbose kytkimell\u00e4 voit tulostaa sek\u00e4 tilastot ett\u00e4 datan samalle sivulle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --lineno| .\/cstat --verbose\n4351803043136516056288856573724573262070985983534430590448419963596642\n3456174389372153988786921278046617965667514985321851793216687887157932\n1902255648112995719416628601644736570744967017380038762966609076622811\n1281509743204688618205185045706022024422762995194550322958445377790472\n3784413827708402970490417813213564250017238858771981034500700507530704\n9055168367119912878629899714626335171522022670864908592668742446542918\n0191677706669306365217622375825024795059935366760530044265382851611997\n3416723466929675866231727509034129352233311007024186331113208959024698\n2335185850752231213099177908357629831877249743371602035678155510036859\n7946039351097931583962995307389998234628068269367172182854699685499923\nctrl      LF:10\nchars     0:69, 1:69, 2:76, 3:70, 4:56, 5:70, 6:77, 7:73, 8:66, 9:74, total:700\ncdiff     0:1, 1:1, 2:-6, 3:0, 4:14, 5:0, 6:-7, 7:-3, 8:4, 9:-4, total:0\ncstats    min:56, max:77, total:700, count:10, average:70, characters:700, utf8first:0, utf8other:0, ascii:700, ctrl:10, entropy:3.316983\nmultiple1 singles:700, twins:87, triplets:11, total:798\nm1expect  singles:700, twins:70, triplets:7, total:777\nm1diff    singles:0, twins:-17, triplets:-4, total:-21\nmultiple2 singles:537, twins:65, triplets:11, total:700\nm2expect  singles:567, twins:56, triplets:5, total:694\nm2diff    singles:30, twins:-9, triplets:-6, total:15\nm2dist    singles:1, twins:10, triplets:63, total:700<\/code><\/pre>\n\n\n\n<p>Oletuksena kaikki tulostettavat tilastorivit tulostetaan. &#8211;all k\u00e4\u00e4nt\u00e4\u00e4 kaikki rivit (ei tulosteta\/tulostetaan). Jos haluat tulostaa pelk\u00e4st\u00e4\u00e4n &#8211;chars rivin, se voidaan tehd\u00e4 n\u00e4in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single -x -s8 -w8 -l1000 --lineno | .\/cstat --all --chars\nchars     0:4072, 1:3952, 2:3970, 3:4189, 4:4014, 5:3898, 6:4055, 7:3969, 8:3934, 9:4000, a:4089, b:3957, c:4013, d:3944, e:3971, f:3973, total:64000<\/code><\/pre>\n\n\n\n<p>Seuraavassa ajossa newressua ajetaan useita kertoja, ja tulostetaan raportti ensimm\u00e4isen merkin satunnaisuudesta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat newressuruns.sh\n#!\/bin\/bash\necho \"Statistics for first character on multiple runs of newressu: (.\/newressu --single --bin $@ -w1 -s1 --lineno -l1)\"\nrm -f newressuruns.rnd; for ((c=0;c&lt;10000;c++)); do .\/newressu --single --bin $@ -w1 -s1 --lineno -l1 &gt;&gt;newressuruns.rnd; done; cat newressuruns.rnd | .\/newressutest7; rm -f newressuruns.rnd\n$ .\/newressuruns.sh\nStatistics for first character on multiple runs of newressu: (.\/newressu --single --bin  -w1 -s1 --lineno -l1)\nctrl      LF:10000\nchars     0:5046, 1:4954, total:10000, min:4954, max:5046\ncdiff     0:-46, 1:46, total:0, min:-46, max:46\ncstats    min:4954, max:5046, total:10000, count:2, average:5000, characters:10000, utf8first:0, utf8other:0, ascii:10000, ctrl:10000, entropy:0.999939\nmultiple1 singles:10000, twins:4950, triplets:2457, quadruplets:1236, quintuplets:608, sixlets:308, 7lets:150, 8lets:71, 9lets:36, 10lets:18, 11lets:7, 12lets:1, total:19842\nm1expect  singles:10000, twins:5000, triplets:2500, quadruplets:1250, quintuplets:625, sixlets:312, 7lets:156, 8lets:78, 9lets:39, 10lets:19, 11lets:9, 12lets:4, 13lets:2, 14lets:1, total:19995\nm1diff    singles:0, twins:50, triplets:43, quadruplets:14, quintuplets:17, sixlets:4, 7lets:6, 8lets:7, 9lets:3, 10lets:1, 11lets:2, 12lets:3, 13lets:2, 14lets:1, total:153, min:0, max:50\nmultiple2 singles:2557, twins:1272, triplets:593, quadruplets:328, quintuplets:142, sixlets:79, 7lets:44, 8lets:17, 9lets:7, 10lets:5, 11lets:5, 12lets:1, total:10000\nm2expect  singles:2500, twins:1250, triplets:625, quadruplets:312, quintuplets:156, sixlets:78, 7lets:39, 8lets:19, 9lets:9, 10lets:4, 11lets:2, 12lets:1, total:9951\nm2diff    singles:-57, twins:-22, triplets:32, quadruplets:-16, quintuplets:14, sixlets:-1, 7lets:-5, 8lets:2, 9lets:2, 10lets:-1, 11lets:-3, 12lets:0, total:-55, min:-57, max:32\nm2dist    singles:3, twins:7, triplets:16, quadruplets:30, quintuplets:70, sixlets:126, 7lets:227, 8lets:588, 9lets:1428, 10lets:2000, 11lets:2000, 12lets:10000, total:10000\n$<\/code><\/pre>\n\n\n\n<p>Raportin rivit puhuvat sen puolesta ett\u00e4 tilastot toteutuvat my\u00f6s eri ajot ylitt\u00e4viss\u00e4 raporteissa. T\u00e4ss\u00e4 raportti jakautuu puoliksi nolliin ja ykk\u00f6siin, ja se tietysti johtaa siihen ett\u00e4 my\u00f6s datan monikot ovat tilaston mukaisia. Jos meill\u00e4 on datana nolla, todenn\u00e4k\u00f6isyys on 50% ett\u00e4 sen per\u00e4\u00e4n tulee toinen nolla, ja kahden nollan per\u00e4\u00e4n tulee nolla 50% tapauksista. Ressuhan satunnaistaa koko puskurin ennen ensimm\u00e4isen merkin palauttamista.<\/p>\n\n\n\n<p>Toinen ohjelma jonka kirjoitin: t\u00e4ss\u00e4 ideana on etsi\u00e4 satunnaisjonoista tuplia. Tuplien maksimipituuden ja m\u00e4\u00e4r\u00e4n pit\u00e4isi korreloida tiedoston tietueiden m\u00e4\u00e4r\u00e4n kanssa. Esimerkiksi 64 merkki\u00e4 pitki\u00e4 tuplia ei pit\u00e4isi tulla, niiden todenn\u00e4k\u00f6isyys on niin pieni. &#8211;stat kytkimell\u00e4 on aloiteltu tilaston laskemista, se on kuitenkin kesken. Ohjelma on nimetty uudelleen newressutest11:ksi ja komentoriviparametrej\u00e4 on muutettu selke\u00e4mm\u00e4ksi. Toki ohjelman mallikomennot jatkussa tarvitsevat uudet parametrit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;math.h&gt;\n#include &lt;ctype.h&gt;\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressutest11\/newressutest version 0.5 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2022-2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FILESIZE 210\n#define BINSIZE 10 \/\/ bytes per line\n#define LINESIZE 21 \/\/ BINSIZE * 2 + 1\n#define LINES 10\n#define BLOCKSIZE 1024\n\n#define GENT_SIZE 128\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\nextern int verbose;\n\n#define INPUT_RESSU 0\n#define INPUT_PSEUDORESSU 1\n#define INPUT_FASTRESSU 2\n#define INPUT_SINGLERESSU 3\n#define INPUT_RDRAND 4\n#define INPUT_RDSEED 5\n#define INPUT_URANDOM 6\n#define INPUT_RANDOM 7\n\n#define USE_RDRAND 2\n#define USE_RDSEED 2\n\nstatic unsigned char urandomfilename&#91;128] = \"\/dev\/urandom\";\n#ifdef USE_RANDOM\nstatic unsigned char randomfilename&#91;128] = \"\/dev\/random\";\n#endif\n\nstatic void readfile_xor(int size,\n    unsigned char *buffer,\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\")) != NULL) {\n    while(size != 0) {\n      n = (size &lt; sizeof(temp)) ? size : sizeof(temp);\n      n2 = fread(temp, 1, n, fp1);\n      for(c = 0; c &lt; n2; c++)\n        buffer&#91;c] ^= temp&#91;c];\n      size -= n2;\n      buffer += n2;\n    }\n    fclose(fp1);\n  }\n}\n\nint input = 0;\n\nvoid ressu_genbytes(int size, unsigned char *buffer);\nvoid pseudoressu_bytes(int size, unsigned char *buffer);\nvoid ressu_genbytes_fast(int size, unsigned char *buffer);\nvoid ressu_genbytes_single(int size, unsigned char *buffer);\n\n#if defined INPUT_RDRAND || defined INPUT_RDSEED\n#include \"fort.h\"\n#endif\n\nint ressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n\n    if(input == INPUT_RESSU) \/\/ ressu prod\n      ressu_genbytes(sizeof(gent), gent);\n\n#ifdef SHA256\n    else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n      pseudoressu_bytes(sizeof(gent), gent);\n\n#endif\n    else if(input == INPUT_FASTRESSU) \/\/ ressu_fast\n      ressu_genbytes_fast(sizeof(gent), gent);\n\n    else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n      ressu_genbytes_single(sizeof(gent), gent);\n\n#ifdef INPUT_RDRAND\n    else if(input == INPUT_RDRAND) \/\/ intel rdrand\n      rdrand_bytes(sizeof(gent), gent);\n\n#endif\n#ifdef INPUT_RDSEED\n    else if(input == INPUT_RDSEED) \/\/ intel rdseed\n      rdseed_bytes(sizeof(gent), gent);\n\n#endif\n    else if(input == INPUT_URANDOM) \/\/ urandom\n      readfile_xor(sizeof(gent), gent, urandomfilename);\n\n#ifdef USE_RANDOM\n    else if(input == INPUT_RANDOM) \/\/ random\n      readfile_xor(sizeof(gent), gent, randomfilename);\n\n#endif\n    else {\n      fprintf(stderr,\"%s: mode '%d' not available\\n\",\n\t      procname, input);\n      exit(2);\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\nunsigned long ressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;      \n      bytes = 7;\n\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | ressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n  return(word);\n}\n\n#include &lt;string.h&gt;\n#include &lt;stdlib.h&gt;\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nint stat = 0;\n\n#ifdef NOTUSED\n\nvoid fprintfdouble(FILE *fp1, unsigned char *text, double number)\n{\n  int c;\n  unsigned char buffer&#91;64];\n  \n  sprintf(buffer,\"%f\", number);\n\n  \/\/ remove ending zeroes\n  \n  for(c = strlen(buffer) - 1; c &gt; 0 &amp;&amp; buffer&#91;c] == '0'; c--)\n    buffer&#91;c] = '\\0';\n\n  \/\/ remove ending dot\n  \n  if(buffer&#91;strlen(buffer) - 1] == '.')\n    buffer&#91;strlen(buffer) - 1] = '\\0';\n\n  fprintf(fp1, \"%s\", buffer);\n  fprintf(fp1, \"%s\", text);\n}\n\n#endif\n\n#ifdef KOK\n\ndouble fact(long n)\n{\n  unsigned long l;\n  double result = 1;\n\n  for(l = 1; l &lt;= n; l++) {\n    result = result * l;\n  }\n  return(result);\n}\n\n#endif\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p)\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2)\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n\n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\n#define DEBUG45 2\n\nunsigned long long getlonglong(unsigned char *p2)\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value:%d\", digit);\n      fprintf(stderr,\", base:%u(\", base);\n      readablelonglong(stderr, base);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", ll:%llu(\", prevll);\n      readablelonglong(stderr, prevll);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", multiplier:%llu(\", multiplier);\n      readablelonglong(stderr, multiplier);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n      exit(1);\n\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG45\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%u(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value:%d\", digit);\n    fprintf(stderr,\", base:%u(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  return(totll);\n}\n\n#define FILE_HASH 2 \/\/ on by default\n\n#ifdef FILE_HASH\n\nvoid hashfinal2string(unsigned char *hashstring, unsigned char *final)\n{\n  for(int c = 0; c &lt; HashLen; c++) {\n    sprintf(hashstring + 2 * c, \"%02x\", final&#91;c]);\n  }\n}\n\n#endif\n\n#define DEBUG79 2\n\nextern unsigned int fixedclockchainlength;\nint clockmode; \/\/ 0 = normal, 1 = fixed\nvoid ressu_setclock(int);\n\nint main(int argc, char *argv&#91;])\n{\n  int c, percentageline = 1, prevpros, pros, quiet = 0, help = 0;\n  int filesize_set = 0, binsize_set = 0, linesize_set = 0, lines_set = 0;\n  unsigned long long filesize = FILESIZE, lines = LINES;\n  unsigned int binsize = BINSIZE, linesize = LINESIZE;\n  int stdoutflag = 0;\n  unsigned long long plines = 0;\n  unsigned char *buffer, filename&#91;128] = \"\";\n  FILE *fp1;\n  \n  procname = argv&#91;0];\n\n#ifdef KOK\n  long l, l2;\n  for(long l = 1; l &lt; 10; l++) {\n    fprintf(stderr,\"c:%ld\", l);\n    l2 = fact(l);\n    fprintf(stderr,\", result:%ld\", l2);\n    fprintf(stderr,\"\\n\");\n  }\n#endif\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(c == argc - 1 &amp;&amp; !strcmp(argv&#91;c], \"-\")) { \/\/ last option hyphen\n      stdoutflag = 1; \/\/ output to stdout\n      continue;\n    }\n    \n    if(strncmp(\"-\", argv&#91;c], 1)) { \/\/ filename not expected\n      fprintf(stderr,\"%s: filename not expected\", procname);\n      fprintf(stderr,\", parameter:%s\", argv&#91;c]);\n      fprintf(stderr,\"\\n\");\n      exit(1);\n    }\n    \n    if(!strncmp(\"-\", argv&#91;c], 1)) { \/\/ option starting with hyphen\n      \n      if(!strncmp(\"-o\", argv&#91;c], 2)) { \/\/ output filename\n\tif(*(argv&#91;c] + 2) != '\\0') {\n\t  strncpy(filename, argv&#91;c] + 2, sizeof(filename));\n\t} else if(c + 1 &lt; argc) {\n\t  strncpy(filename, argv&#91;c + 1], sizeof(filename));\n\t  c++;\n\t}\n\tstdoutflag = 0;\n\t\n      } else if(!strcmp(\"--stdout\", argv&#91;c])) { \/\/ output stdout\n\tstdoutflag = 1; \/\/ output to stdout\n\tfilename&#91;0] = '\\0';\n\t\n      } else if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c]) ) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tverbose = !verbose;\n\n      } else if(!strcmp(\"--quiet\", argv&#91;c])) {\n\tquiet = !quiet;\n\n      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--linesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  linesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  linesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlinesize_set = 1;\n\t\n      } else if(!strncmp(\"--lines\", argv&#91;c], 7)) {\n\tif(*(argv&#91;c] + 7) != '\\0') {\n\t  lines = getlonglong(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  lines = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlines_set = 1;\n\n      } else if(!strncmp(\"--binsize\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  binsize = getlonglong(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc) {\n\t  binsize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tbinsize_set = 1;\n\n      } else if(!strcmp(\"--stat\", argv&#91;c])) {\n\tstat = !stat;\n\n      } else if(!strcmp(\"--ressu\", argv&#91;c])) {\n\tinput = INPUT_RESSU;\n\n      } else if(!strcmp(\"--pseudoressu\", argv&#91;c])) {\n\tinput = INPUT_PSEUDORESSU;\n\n      } else if(!strcmp(\"--fastressu\", argv&#91;c]) ||\n\t\t!strcmp(\"--fast\", argv&#91;c])) {\n\tinput = INPUT_FASTRESSU;\n\n      } else if(!strcmp(\"--singleressu\", argv&#91;c]) ||\n\t\t!strcmp(\"--single\", argv&#91;c])) {\n\tinput = INPUT_SINGLERESSU;\n\n#ifdef INPUT_RDRAND\n      } else if(!strcmp(\"--rdrand\", argv&#91;c])) {\n\tinput = INPUT_RDRAND;\n\n#endif\n#ifdef INPUT_RDSEED\n      } else if(!strcmp(\"--rdseed\", argv&#91;c])) {\n\tinput = INPUT_RDSEED;\n\n#endif\n      } else if(!strcmp(\"--urandom\", argv&#91;c])) {\n\tinput = INPUT_URANDOM;\n\n#ifdef USE_RANDOM\n      } else if(!strcmp(\"--random\", argv&#91;c])) {\n\tinput = INPUT_RANDOM;\n\n#endif\n      } else if(!strncmp(\"--fixedclock\", argv&#91;c], 12)) {\n\tif(*(argv&#91;c] + 12)!='\\0' &amp;&amp; atoi(argv&#91;c] + 12) &gt; 1) {\n\t  fixedclockchainlength = atoi(argv&#91;c] + 12);\n\t  clockmode = 1;\n\t} else if(c + 1 &lt; argc &amp;&amp; atoi(argv&#91;c + 1]) &gt; 1) {\n\t  fixedclockchainlength = atoi(argv&#91;c + 1]);\n\t  clockmode = 1;\n\t  c++;\n\t} else {\n\t  clockmode = !clockmode;\n\t}\n\n\tif(fixedclockchainlength &lt; 5 ||\n\t   fixedclockchainlength &gt; 255)\n\t  fixedclockchainlength = 50;\n\n\tressu_setclock(clockmode);\n \t\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    }\n  }\n\n  if(!linesize_set)\n    linesize = binsize * 2 + 1;\n  else if(!binsize_set)\n    binsize = (linesize - 1) \/ 2;\n\n  if(!filesize_set)\n    filesize = lines * linesize;\n  else if(!lines_set) {\n    lines = (filesize + linesize - 1) \/ linesize; \/\/ round up\n    filesize = lines * linesize;\n  } else if(!linesize_set) {\n    linesize = (filesize + lines - 1) \/ lines; \/\/ round up\n    if((linesize &amp; 1) == 0) \/\/ up to x * 2 + 1\n      linesize++;\n    binsize = (linesize - 1) \/ 2;\n    filesize = lines * linesize;\n  }\n\n#define aEXFAT_FIX 2\n  \n#ifdef EXFAT_FIX\n  \n  if(linesize &gt;= KILO * KILO) { \/\/ max linesize 1m (exfat)\n    linesize = KILO * KILO - 1;\n    binsize = (linesize - 1) \/ 2;\n    lines = (filesize + linesize - 1) \/ linesize;\n    filesize = lines * linesize;\n  }\n\n#endif\n  \n  if(linesize != binsize * 2 + 1 ||\n     linesize &lt; 3 || binsize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", binsize:%u(\", binsize);\n    readablelonglong(stderr, binsize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize != lines * linesize ||\n     lines &lt; 1 || linesize &lt; 3) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize \/ lines != linesize) { \/\/ test overflow too\n    fflush(stdout);\n    fprintf(stderr,\"%s: parameter overflow\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\", procname);\n    fprintf(stderr,\"\\n\\t&#91;-o filename]\");\n    \/\/fprintf(stderr,\" &#91;--stdout]\");\n    fprintf(stderr,\"\\n\\t&#91;--filesize base-number-multiplier]\"); \n    fprintf(stderr,\"\\n\\t&#91;--lines base-number-multiplier]\");\n    fprintf(stderr,\" &#91;--linesize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--binsize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--ressu]\");\n    fprintf(stderr,\" &#91;--pseudoressu]\");\n    fprintf(stderr,\" &#91;--fastressu]\");\n    fprintf(stderr,\" &#91;--singleressu]\");\n#ifdef INPUT_RDRAND\n    fprintf(stderr,\" &#91;--rdrand]\");\n#endif\n#ifdef INPUT_RDSEED\n    fprintf(stderr,\" &#91;--rdseed]\");\n#endif\n    fprintf(stderr,\" &#91;--urandom]\");\n#ifdef USE_RANDOM\n    fprintf(stderr,\" &#91;--random]\");\n#endif\n    fprintf(stderr,\" &#91;--fixedclock]\");\n    fprintf(stderr,\"\\n\\t&#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--stat]\");\n    fprintf(stderr,\" &#91;--verbose]\");\n    fprintf(stderr,\" &#91;--quiet]\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Examples:\\n\");\n    fprintf(stderr,\"\\t$ %s --single --filesize1g\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --lines1m\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --linesize25\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --binsize12\\n\", procname);\n    exit(1);\n  } \/\/ end of if(help)\n\n#ifdef DEBUG79\n\n  \/\/ print filesize parameters\n  \n  fprintf(stderr,\"input:%d\", input);\n  fprintf(stderr,\", lines:%llu(\", lines);\n  readablelonglong(stderr, lines);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", binsize:%u(\", binsize);\n  readablelonglong(stderr, binsize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", linesize:%u(\", linesize);\n  readablelonglong(stderr, linesize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n  \n#endif\n  \n  if(!stdoutflag &amp;&amp; filename&#91;0] == '\\0') {\n\n    \/\/ find first available filename,\n    \/\/ or empty \"slot\"\n\n    for(c = 1; c &lt;= 99999; c++) {\n      sprintf(filename, \"newressutest11.%d.rnd\", c);\n      if((fp1 = fopen(filename, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n\n#ifdef FILE_HASH\n      unsigned char filename2&#91;138];\n      sprintf(filename2,\"%s.sha256\", filename);\n      if((fp1 = fopen(filename2, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n#endif\n\n      break;\n    }\n  }\n\n  if(stdoutflag) {\n    if(isatty(STDOUT_FILENO)) { \/\/ 0=stdin, 1=stdout, 2=stderr\n      percentageline = 0;\n    }\n  }\n    \n  if(stdoutflag) \n    fprintf(stderr,\"filename:-\\n\");\n  else\n    fprintf(stderr,\"filename:%s\\n\", filename);\n    \n  if(stdoutflag == 1) {\n    fp1 = stdout;\n  } else if((fp1 = fopen(filename, \"w\")) == NULL) {\n    fprintf(stderr,\"%s: cannot open file\", procname);\n    fprintf(stderr,\", filename:%s\", filename);\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  }\n  \n  if(stat) {\n  }\n\n#ifdef FILE_HASH\n  \n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n\n  HashInit(&amp;hash); \/\/ initialize hash\n\n#endif\n  \n  if((buffer = malloc(linesize + 1)) == NULL) { \/\/ space for '\\0' too\n    fprintf(stderr,\"%s: cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n  }\n\n  memset(buffer, 0, linesize + 1);\n\n#ifdef EXFAT_FIX\n  \n  int mbinlines = (KILO * KILO) \/ linesize;\n  if(mbinlines == 0)\n    mbinlines = 1;\n  fprintf(stderr,\"mbinlines:%d\\n\", mbinlines);\n\n#endif\n  \n  prevpros = -1;\n  \n  \/\/ fill first hex string\n\n  for(c = 0; c &lt; binsize; c++)\n    sprintf(buffer + c * 2, \"%02x\", (unsigned int)ressu_gen_limit(256));\n  buffer&#91;linesize - 1] = '\\n';\n  buffer&#91;linesize] = '\\0';\n  \n  for(;;) {\n\n    \/\/ bug! this program produces fixed length records\n    \/\/ and for some reason records end up being variable\n    \/\/ length records when they reach my removable usb\n    \/\/ drive (exfat). I am hoping this is silly one.\n    \/\/ next if() checks record length, and prints stars for\n    \/\/ variable length records. Havent seen stars yet...\n    \/\/ seems that fflush(), sync() fixes the problem.\n    \n    if(linesize != strlen(buffer)) {\n      fprintf(stderr,\"*\");\n      fflush(stderr);\n    }\n    \n#ifdef FILE_HASH\n    HashUpdate(&amp;hash, buffer, linesize); \/\/ calculate hash\n#endif\n      \n    if(fwrite(buffer, 1, linesize, fp1) &lt; linesize) {\n      fprintf(stderr,\"%s:\", procname);\n      fprintf(stderr,\" cannot write file\");\n      fprintf(stderr,\"\\n\");\n      exit(1);      \n    }\n    \n#ifdef EXFAT_FIX\n\n    if(plines &gt; 0 &amp;&amp; plines % mbinlines == 0) { \/\/ fflush and sync (EXFAT)\n      fflush(stdout);\n      sync();\n    }\n\n#endif\n    \n    plines++;\n    if(plines &gt;= lines)\n      break;\n\n    \/\/ remove first byte\n\n    memmove(buffer, buffer + 2, linesize - 1);\n\n    \/\/ add new last byte\n\n    sprintf(buffer + linesize - 3, \"%02x\", (unsigned int)ressu_gen_limit(256));\n\n    buffer&#91;linesize - 1] = '\\n';\n    buffer&#91;linesize] = '\\0';\n    \n    if(percentageline) { \/\/ &amp;&amp; !quiet) {\n      pros = (int)((double) plines \/ lines * 1000);\n      if(prevpros != pros) {\n\tfflush(stdout);\n\tprevpros = pros;\n\tfprintf(stderr,\"\\rDone:%d.%d%%\", pros \/ 10, pros % 10);\n\tfflush(stderr);\n      }\t\n    }\n  }\n\n#ifdef FILE_HASH\n  HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n  \n  if(percentageline) { \/\/ &amp;&amp; !quiet) {\n    fprintf(stderr,\"\\rDone:100.0%%  \\n\");\n  }\n\n#ifdef EXFAT_FIX\n  \n  fflush(stdout); \/\/ fflush and sync (EXFAT)\n  sync();\n\n#endif\n  \n  if(!stdoutflag)\n    fclose(fp1);\n  \n#ifdef FILE_HASH\n\n  unsigned char hashstring&#91;2 * HashLen + 1];\n  \n  hashfinal2string(hashstring, digest);\n  \n  fprintf(stderr,\"%s: hashed file\", procname);\n\n  if(filename&#91;0] != '\\0') {\n    fprintf(stderr,\", filename:%s\", filename);\n\n    unsigned char filename2&#91;138];\n\n    sprintf(filename2,\"%s.sha256\", filename);\n\n    fprintf(stderr,\", hashfilename:%s\", filename2);\n\n    if((fp1 = fopen(filename2, \"w\")) != NULL) {\n      fprintf(fp1,\"%s\\n\", hashstring);\n      fclose(fp1);\n    }\n  } \/\/ end of if(filename&#91;0] != '\\0'\n  \n  fprintf(stderr,\", sha256:%s\\n\", hashstring);\n\n  if(!stdoutflag) {\n    fprintf(stderr,\"%s: checking sha256\", procname);\n    fprintf(stderr,\", filename:%s\\n\", filename);\n    unsigned char command&#91;1024];\n    sprintf(command,\"sha256sum %s\", filename);\n    system(command);\n  }\n  \n#endif\n  \n  free(buffer);\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>Ohjelma tulostaa seuraavanlaisen raportin: raportin voi kirjoittaa suurelle kovalevylle, sortata ja tulostaa &#8220;tuplatietueet&#8221; uniq &#8211;check-chars=x optiolla. Lis\u00e4\u00e4  -b toiminnolla riville tulostettavia heksamerkkej\u00e4, ja -l optiolla rivej\u00e4 sopivasti: seuraavassa rivill\u00e4 on 30 merkki\u00e4 ja rivej\u00e4 on 30. Katso tulostettavan tiedoston koko input: rivilt\u00e4. T\u00e4ss\u00e4 1030 merkki\u00e4 eli ~1 kb.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest -b30 -l30\ninput:0, lines:30(0x1e), bytes:30(0x1e), total:1830b(0Tb,0Gb,0Mb,1Kb)\na4721b581d93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f9\n721b581d93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f938\n1b581d93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804\n581d93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d8\n1d93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88a\n93beb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad8\nbeb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f\nb37b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4f\n7b3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc2\n3de11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258\ne11d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4\n1d86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9\n86064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c901\n064be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b\n4be32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07\ne32c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e1\n2c14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114\n14ffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4\nffecee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e495\necee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d\nee00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d69\n00b14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947\nb14e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1\n4e8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd\n8abfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52\nbfa27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52ca\na27b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52ca66\n7b63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52ca662b\n63f93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52ca662b0a\nf93804d88ad87f4fc258c4c9017b07e114e4951d6947c1cd52ca662b0a36\n$<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest\ninput:0, lines:10(0xa), bytes:16(0x10), total:330b(0Tb,0Gb,0Mb,0Kb)\nc80275eea3c4485e51afafaef99ed554\n0275eea3c4485e51afafaef99ed554b1\n75eea3c4485e51afafaef99ed554b16f\neea3c4485e51afafaef99ed554b16fdc\na3c4485e51afafaef99ed554b16fdc12\nc4485e51afafaef99ed554b16fdc12ec\n485e51afafaef99ed554b16fdc12ecda\n5e51afafaef99ed554b16fdc12ecda9f\n51afafaef99ed554b16fdc12ecda9f3d\nafafaef99ed554b16fdc12ecda9f3d3e<\/code><\/pre>\n\n\n\n<p>Pieni bugiv\u00e4like: Edellinen ohjelma tuottaa kiinte\u00e4n mittaisia tietueita, mutta jostain syyst\u00e4 tietueen pituudet vaihtelevat nelj\u00e4 teraisella usb levyll\u00e4ni. Siksi tietueen pituuden tarkistava iffi edellisess\u00e4 ohjelmassa. Mielest\u00e4ni ongelman ei pit\u00e4isi olla ohjelmassa.<\/p>\n\n\n\n<p>Pituuden tarkistusohjelma, joilla yritin etsi\u00e4 ongelmapaikkaa. T\u00e4ss\u00e4 ohjelma, jolla voi tarkistaa inputin tietueiden pituudet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;string.h&gt;\n\n#define BUFLEN 1024\n\nvoid main(int argc, unsigned char *argv&#91;])\n{\n  unsigned long count;\n  unsigned char buffer&#91;BUFLEN];\n  unsigned int inputlen = -1;\n\n  count = 0;\n  \n  while(fgets(buffer, BUFLEN, stdin)) {\n    if(inputlen == -1) {\n      inputlen = strlen(buffer);\n      fprintf(stdout,\"line length: %d\\n\",inputlen);\n      fflush(stdout);\n    } else if(inputlen != strlen(buffer)) {\n      fprintf(stdout,\" %lu\",count);\n    }\n    count += strlen(buffer);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n}<\/code><\/pre>\n\n\n\n<p>Esimerkkej\u00e4 tarkistusohjelman ajosta: ensimm\u00e4inen esimerkki<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest --pseudoressu -b20 -l1000 | .\/newressutest6\ninput:1, lines:1000(0x3e8), bytes:20(0x14), total:41000b(0Tb,0Gb,0Mb,41Kb)\nline length: 41<\/code><\/pre>\n\n\n\n<p>Toinen esimerkki, joka tarkastaa sortin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest --pseudoressu -b20 -l1000 | sort | .\/newressutest6\ninput:1, lines:1000(0x3e8), bytes:20(0x14), total:41000b(0Tb,0Gb,0Mb,41Kb)\nline length: 41<\/code><\/pre>\n\n\n\n<p>Kolmas. jossa tarkistetaan tehty tiedosto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest --pseudoressu -b20 -l1000 | sort &gt; newressutest.deb\ninput:1, lines:1000(0x3e8), bytes:20(0x14), total:41000b(0Tb,0Gb,0Mb,41Kb)\n$ cat newressutest.deb | .\/newressutest6\nline length: 41<\/code><\/pre>\n\n\n\n<p>Bugilis\u00e4ke jatkuu: Yksi l\u00f6yt\u00e4m\u00e4ni bugikohta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>365827042:d717d9ccb5635fbf20a67feac0113f7792c55bb3d25f0f8f334ff89859fad697720c494f8cb33189cab70d7dd4fc648f4f90dbfb9f56f82\\\ne556be36aa2928151f3957d5b859dc8930b954d042b7479d24d17300c88cdd3652a746a0f22339686ab42582bd661d28b28a0664bb9333964e271c7d3\\\nb94a38f3bc80e1fc97da6571\n365827043:17d9ccb5635fbf20a67feac0113f7792c55bb3d25f0f8f334ff89859fad697720c494f8cb33189cab70d7dd4fc648f4f90dbfb9f56f82e5\\\n56be36aa2928151f3957d5b859dc8930b954d042b7479d24d17300c88cdd3652a746a0f22339686ab42582bd661d28b28a0664bb9333964e271c7d3b9\\\n4a38f3bc80e1fc97da65712f\n365827044:d9ccb5635fbf20a67feac0113f7792c55bb3d25f0f8f334ff89859fad697720c494f8cb33189cab70d7dd4fc648f4f90dbfb9f56f82e556\\\nbe36aa2928151f3957d5b859dc8930b954d042b7479d24d17300c88cdd3652a746a0f22339686ab42582bd661d28b28a0664bb9333964e271c7d3b94a\\\n38f3bc80e1fc97da65712fd2\n365848983:8e4431f3089c25af75df2677b0f511e1a690be147c4e01d766825d0220701b2a796cf75a13ae23a483cb1477968bca63ba43d2d3f8e555d\\\na7e742164c3e0495b3520359ca985c8908e5618d24e9a22b15febb22f7cff226ed717d9ccb5635fbf20a67feac0113f7792c55bb3d25f0f8f334ff8\n365848984:d5103f7429fc7e930327d21a283ced3798d280005fcf34e29ab15d3e50259d137ab5cc3fab3ebc4bb3fbfcc5ea90cdb3310f961de4f4371\\\n46981e282292099c137e555da7e742164c3e0495b3520359ca985c8908e5618d24e9a22b15febb22f7cff226ed717d9ccb5635fbf20a67feac0113f77\\\n92c55bb3d25f0f8f334ff898\n365848985:103f7429fc7e930327d21a283ced3798d280005fcf34e29ab15d3e50259d137ab5cc3fab3ebc4bb3fbfcc5ea90cdb3310f961de4f437146\\\n981e282292099c137e555da7e742164c3e0495b3520359ca985c8908e5618d24e9a22b15febb22f7cff226ed717d9ccb5635fbf20a67feac0113f7792\\\nc55bb3d25f0f8f334ff89859\n365848986:3f7429fc7e930327d21a283ced3798d280005fcf34e29ab15d3e50259d137ab5cc3fab3ebc4bb3fbfcc5ea90cdb3310f961de4f43714698\\\n1e282292099c137e555da7e742164c3e0495b3520359ca985c8908e5618d24e9a22b15febb22f7cff226ed717d9ccb5635fbf20a67feac0113f7792c5\\\n5bb3d25f0f8f334ff89859fa\n<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 esimerkki tuplaohjelman ajosta: voit esimerkiksi kasvatella rivim\u00e4\u00e4r\u00e4\u00e4 -l1000 kytkimen numeroa kasvattamalla, ja tulostettavien tuplien pituutta &#8211;check-chars=6 numeroa kasvattamalla. Varmistathan ett\u00e4 -b32 on riitt\u00e4v\u00e4n suuri, T\u00e4ss\u00e4 on l\u00f6ytynyt 2 tuplaa, 07-alkuinen ja 19-alkuinen. Tietenkin tuplat ovat 6 merkin pituisia. Maksimituplien pituuden ja m\u00e4\u00e4r\u00e4n pit\u00e4isi korreloida rivim\u00e4\u00e4r\u00e4n kanssa. T\u00e4ss\u00e4 haittana on ett\u00e4 satunnaisrivit eiv\u00e4t j\u00e4\u00e4 talteen, eli niille ei voi tehd\u00e4 jatkotutkimusta (esimerkiksi ajaa useampia uniq:ita samalle materiaalille). Voit tarkistaa my\u00f6s ett\u00e4 rivin lopussa (raportoidun tuplan j\u00e4lkeen) ei ole liikaa lis\u00e4\u00e4 samanlaisia merkkej\u00e4, liian pitk\u00e4 tupla olisi ongelma.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest -b32 -l10000 | sort | uniq -D --check-chars=6\ninput:0, lines:10000(0x2710), bytes:32(0x20), total:650000b(0Tb,0Gb,0Mb,650Kb)\n0764007efc362b5ddeaee81fe76561cae82728f988a70d3938eab5cc41b0e590\n076400c3ad198728dc05d74862dbe2380696efc580f1f809c3eafa4c333d9ff5\n1919f52e36204b0f2cb49ecd5a59b756fcb020db2c7dbf6d87005e8232c86f37\n1919f5f0e0f85884ea321fb0692989e02a281e0bec91201d5e062f10c2f3bf2d<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 on ajettu newressutest11:sta exfat levyll\u00e4. T\u00e4ss\u00e4 versiossa on jo fflush ja sync kutsut. 256 gigainen tiedosto on ajettu onnistuneesti. Ajossa l\u00f6ytyi 4 tuplaa 32, 55, 77 ja 97 alkuiset. Kaikki tuplat ovat 16 pitki\u00e4, eik\u00e4 niiss\u00e4 ole samoja merkkej\u00f6 16 merkin j\u00e4lkeen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>media$ .\/newressutest11 --single --filesize256g | sort -T.\/temp\/ | uniq -D --check-chars=16\nstring:'256g', base:10, multiplier:1073741824, prevll:256, ll:274877906944, totll:274877906944\ninput:3, lines:13089424141(~12G), binsize:10(10B), linesize:21(21B), filesize:274877906961(~256G)\nfilename:-\ndone:100.0%  \n.\/newressutest11: hashed file, sha256:f459507a66824e6e83b98d044c49bb39243bb320fb475158d9a6acedb8e34bcd\n32630a8e6ddcc9406ba7\n32630a8e6ddcc940be5d\n5548db9879bbd10c5499\n5548db9879bbd10c62c2\n777432efb42ea3a89ca3\n777432efb42ea3a8ce06\n971fd08fa651e6980065\n971fd08fa651e6985c9c\nmedia$ \n<\/code><\/pre>\n\n\n\n<p>Kolmas ohjelma tulostaa raportin, josta voi vertailla monikkojen eri merkkien esiintymist\u00e4. Chars rivi on kuten ennenkin yksitt\u00e4isten eri merkkien esiintym\u00e4t yhteens\u00e4. Chars rivill\u00e4 on my\u00f6s keskiarvo kokonaislukuna. Diff(eill\u00e4) rivill\u00e4 on ero tilastolliseen m\u00e4\u00e4r\u00e4\u00e4n. m1digits singles rivill\u00e4 on yks\u00f6sten m\u00e4\u00e4r\u00e4t (erikseen &#8216;0&#8217;, &#8216;1&#8217;, &#8230; &#8216;f&#8217;) t\u00e4ll\u00e4 tulosteella (&#8211;hex). Vastaavasti m1digdiff rivill\u00e4 on erot tilastoon. Erojen pit\u00e4isi olla sek\u00e4 positiivisia ett\u00e4 negatiivisia suhteellisen pieni\u00e4 arvoja. dexp kent\u00e4ss\u00e4 on odotettu m\u00e4\u00e4r\u00e4. Twins, triplets, quadruplets ja quintuplets rivej\u00e4 luetaan samalla tavalla kun singles rivej\u00e4. Multiple1, m1exp, m1diff, multiple2, m2exp ja m2diff rivit ovat samankaltaisia kun edellisell\u00e4 tulosteella.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --lineno --space --hex -l10000 | .\/newressutest8\nctrl      LF:10000, space:130000\nchars     0:35215, 1:34828, 2:34811, 3:34884, 4:34798, 5:35748, 6:35354, 7:34477, 8:35022, 9:34711, a:35015, b:34997, c:35401, d:34890, e:34756, f:35093, total:560000, count:16, average:35000, total:560000, min:34477, max:35748\ncdiff     0:-215, 1:172, 2:189, 3:116, 4:202, 5:-748, 6:-354, 7:523, 8:-22, 9:289, a:-15, b:3, c:-401, d:110, e:244, f:-93, total:0, min:-748, max:523\nmultiple1 singles:560000, twins:35117, triplets:2606, quadruplets:328, quintuplets:39, sixlets:3, total:598093\nm1exp     singles:560000, twins:35000, triplets:2187, quadruplets:136, quintuplets:8, sixlets:0, total:597331\nm1diff    singles:0, twins:-117, triplets:-419, quadruplets:-192, quintuplets:-31, sixlets:-3, total:-762\nm1digits  singles 0:35215, 1:34828, 2:34811, 3:34884, 4:34798, 5:35748, 6:35354, 7:34477, 8:35022, 9:34711, a:35015, b:34997, c:35401, d:34890, e:34756, f:35093, dexp:35000, total:560000, texp:560000, min:34477, max:35748\nm1digdiff singles 0:-215, 1:172, 2:189, 3:116, 4:202, 5:-748, 6:-354, 7:523, 8:-22, 9:289, a:-15, b:3, c:-401, d:110, e:244, f:-93, total:0, min:-748, max:523\nm1digits  twins 0:2219, 1:2285, 2:2248, 3:2223, 4:2128, 5:2185, 6:2244, 7:2049, 8:2216, 9:2263, a:2142, b:2137, c:2233, d:2226, e:2189, f:2130, dexp:2187, total:35117, texp:35000, min:2049, max:2285\nm1digdiff twins 0:-32, 1:-98, 2:-61, 3:-36, 4:59, 5:2, 6:-57, 7:138, 8:-29, 9:-76, a:45, b:50, c:-46, d:-39, e:-2, f:57, total:-125, min:-98, max:138\nm1digits  triplets 0:167, 1:178, 2:180, 3:163, 4:128, 5:154, 6:153, 7:160, 8:161, 9:170, a:136, b:162, c:173, d:182, e:192, f:147, dexp:136, total:2606, texp:2187, min:128, max:192\nm1digdiff triplets 0:-31, 1:-42, 2:-44, 3:-27, 4:8, 5:-18, 6:-17, 7:-24, 8:-25, 9:-34, a:0, b:-26, c:-37, d:-46, e:-56, f:-11, total:-430, min:-56, max:8\nm1digits  quadruplets 0:24, 1:27, 2:27, 3:21, 4:10, 5:13, 6:22, 7:19, 8:21, 9:17, a:20, b:15, c:23, d:24, e:29, f:16, dexp:8, total:328, texp:136, min:10, max:29\nm1digdiff quadruplets 0:-16, 1:-19, 2:-19, 3:-13, 4:-2, 5:-5, 6:-14, 7:-11, 8:-13, 9:-9, a:-12, b:-7, c:-15, d:-16, e:-21, f:-8, total:-200, min:-21, max:-2\nm1digits  quintuplets 0:6, 1:3, 2:2, 3:2, 4:1, 6:4, 7:3, 8:3, a:4, c:3, d:2, e:5, f:1, dexp:0, total:39, texp:8, min:1, max:6\nm1digdiff quintuplets 0:-6, 1:-3, 2:-2, 3:-2, 4:-1, 6:-4, 7:-3, 8:-3, a:-4, c:-3, d:-2, e:-5, f:-1, total:-39, min:-6, max:-1\nm1digits  sixlets 0:1, a:1, e:1, dexp:0, total:3, texp:0, min:1, max:1\nm1digdiff sixlets 0:-1, a:-1, e:-1, total:-3, min:-1, max:-1\nmultiple2 singles:492372, twins:30233, triplets:1989, quadruplets:253, quintuplets:33, sixlets:3, total:560000\nm2exp     singles:492187, twins:30761, triplets:1922, quadruplets:120, quintuplets:7, sixlets:0, total:559990\nm2diff    singles:-185, twins:528, triplets:-67, quadruplets:-133, quintuplets:-26, sixlets:-3, total:-10\nm2digits  singles 0:30944, 1:30436, 2:30495, 3:30601, 4:30670, 5:31532, 6:31019, 7:30539, 8:30751, 9:30355, a:30867, b:30885, c:31108, d:30620, e:30570, f:30980, dexp:30761, total:492372, texp:492187, min:30355, max:31532\nm2digdiff singles 0:-183, 1:325, 2:266, 3:160, 4:91, 5:-771, 6:-258, 7:222, 8:10, 9:406, a:-106, b:-124, c:-347, d:141, e:191, f:-219, total:-196, min:-771, max:406\nm2digits  twins 0:1909, 1:1956, 2:1915, 3:1918, 4:1882, 5:1890, 6:1960, 7:1748, 8:1915, 9:1940, a:1890, b:1828, c:1910, d:1886, e:1834, f:1852, dexp:1922, total:30233, texp:30761, min:1748, max:1960\nm2digdiff twins 0:13, 1:-34, 2:7, 3:4, 4:40, 5:32, 6:-38, 7:174, 8:7, 9:-18, a:32, b:94, c:12, d:36, e:88, f:70, total:519, min:-38, max:174\nm2digits  triplets 0:125, 1:127, 2:128, 3:123, 4:109, 5:128, 6:113, 7:125, 8:122, 9:136, a:100, b:132, c:130, d:136, e:139, f:116, dexp:120, total:1989, texp:1922, min:100, max:139\nm2digdiff triplets 0:-5, 1:-7, 2:-8, 3:-3, 4:11, 5:-8, 6:7, 7:-5, 8:-2, 9:-16, a:20, b:-12, c:-10, d:-16, e:-19, f:4, total:-69, min:-19, max:20\nm2digits  quadruplets 0:13, 1:21, 2:23, 3:17, 4:8, 5:13, 6:14, 7:13, 8:15, 9:17, a:13, b:15, c:17, d:20, e:20, f:14, dexp:7, total:253, texp:120, min:8, max:23\nm2digdiff quadruplets 0:-6, 1:-14, 2:-16, 3:-10, 4:-1, 5:-6, 6:-7, 7:-6, 8:-8, 9:-10, a:-6, b:-8, c:-10, d:-13, e:-13, f:-7, total:-141, min:-16, max:-1\nm2digits  quintuplets 0:4, 1:3, 2:2, 3:2, 4:1, 6:4, 7:3, 8:3, a:2, c:3, d:2, e:3, f:1, dexp:0, total:33, texp:7, min:1, max:4\nm2digdiff quintuplets 0:-4, 1:-3, 2:-2, 3:-2, 4:-1, 6:-4, 7:-3, 8:-3, a:-2, c:-3, d:-2, e:-3, f:-1, total:-33, min:-4, max:-1\nm2digits  sixlets 0:1, a:1, e:1, dexp:0, total:3, texp:0, min:1, max:1\nm2digdiff sixlets 0:-1, a:-1, e:-1, total:-3, min:-1, max:-1\n$ \n<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 bash:iin perustuva n\u00e4kemys tuplista: (en ole varma n\u00e4kyv\u00e4tk\u00f6 tuplat jossain selaimessa, minulla ne n\u00e4kyv\u00e4t bashissa punaisella)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$.\/newressu | grep \"00\\|11\\|22\\|33\\|44\\|55\\|66\\|77\\|88\\|99\"\n00000 50601770965858790287746351436604015693184573567799066517653601656\n00001 48694546975015201968596666905183123871308274139328912966079898679\n00002 79811004632452834690694925920237574068709382185064173509186665896\n00003 67948756258916859329418821550901897658164278464642949542074825264\n00004 33624858011285146428020109871734597275263223498277932780645159687\n00005 17971792316063297502277999536969560242964320788109401452364923409\n00006 35291566680695002181737688811100316149439988651827176360642157605\n00007 11370134868289458957910751111498131857275527242659407122148439815\n00008 26708050136430661831450323981723744901224836837055153985157327353\n00009 26529141654263551049396906874524955288851596692074733373992155155\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;limits.h&gt;\n#include &lt;math.h&gt;\n\nstatic unsigned char *procname;\nstatic unsigned char *programname = \"newressutest8 version 0.3 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2022-2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nvoid fprintfmultipletype(FILE *fp1, int c)\n{\n  switch(c) {\n    case 0: fprintf(fp1, \"singles\"); break;\n    case 1: fprintf(fp1, \"twins\"); break;\n    case 2: fprintf(fp1, \"triplets\"); break;\n    case 3: fprintf(fp1, \"quadruplets\"); break;\n    case 4: fprintf(fp1, \"quintuplets\"); break;\n    case 5: fprintf(fp1, \"sixlets\"); break;\n    default: fprintf(fp1, \"%dlets\", c + 1); break;\n  }\n}\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, first;\n  int verbose = 0, help = 0, all = 1,\n    ctrl = 1, chars = 1, cdiff = 1,\n    multiple1 = 1, m1exp = 1, m1diff = 1,\n    m1digits = 1, m1digdiff = 1,\n    multiple2 = 1, m2exp = 1, m2diff = 1,\n    m2digits = 1, m2digdiff = 1;\n  char filename&#91;128] = \"-\"; \/\/ default stdin\n  \n  FILE *fp1;\n  \n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(!strcmp(\"-\",argv&#91;c])) { \/\/ filename - --&gt;stdin\n      strncpy(filename, argv&#91;c], sizeof(filename));\n      fp1 = stdin;\n\n    } else if(strncmp(\"-\", argv&#91;c], 1)) { \/\/ filename\n      strncpy(filename, argv&#91;c], sizeof(filename));\n\n    } else if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tverbose = 1;\n\n      } else if(!strcmp(\"--help\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--all\", argv&#91;c])) {\n\n\tall = !all;\n\n\tctrl = all;\n\tchars = all;\n\tcdiff = all;\n\tmultiple1 = all;\n\tm1exp = all;\n\tm1diff = all;\n\tm1digits = all;\n\tm1digdiff = all;\n\tmultiple2 = all;\n\tm2exp = all;\n\tm2diff = all;\n\tm2digits = all;\n\tm2digdiff = all;\n\t\n      } else if(!strcmp(\"--ctrl\", argv&#91;c])) {\n\tctrl = !ctrl;\n\n      } else if(!strcmp(\"--chars\", argv&#91;c])) {\n\tchars = !chars;\n\t\n      } else if(!strcmp(\"--cdiff\", argv&#91;c])) {\n\tcdiff = !cdiff;\n\n      } else if(!strcmp(\"--m1\", argv&#91;c])) {\n\tmultiple1 = !multiple1;\n\tm1exp = !m1exp;\n\tm1diff = !m1diff;\n\tm1digits = !m1digits;\n\tm1digdiff = !m1digdiff;\n\t\n      } else if(!strcmp(\"--m1dig\", argv&#91;c])) {\n\tm1digits = !m1digits;\n\tm1digdiff = !m1digdiff;\n\t\n      } else if(!strcmp(\"--multiple1\", argv&#91;c])) {\n\tmultiple1 = !multiple1;\n\t\n      } else if(!strcmp(\"--m1exp\", argv&#91;c])) {\n\tm1exp = !m1exp;\n\n      } else if(!strcmp(\"--m1diff\", argv&#91;c])) {\n\tm1diff = !m1diff;\n\n      } else if(!strcmp(\"--m1digits\", argv&#91;c])) {\n\tm1digits = !m1digits;\n\t\n      } else if(!strcmp(\"--m1digdiff\", argv&#91;c])) {\n\tm1digdiff = !m1digdiff;\n\n      } else if(!strcmp(\"--m2\", argv&#91;c])) {\n\tmultiple2 = !multiple2;\n\tm2exp = !m2exp;\n\tm2diff = !m2diff;\n\tm2digits = !m2digits;\n\tm2digdiff = !m2digdiff;\n\t\t\n      } else if(!strcmp(\"--m2dig\", argv&#91;c])) {\n\tm2digits = !m2digits;\n\tm2digdiff = !m2digdiff;\n\t\t\n      } else if(!strcmp(\"--multiple2\", argv&#91;c])) {\n\tmultiple2 = !multiple2;\n\n      } else if(!strcmp(\"--m2exp\", argv&#91;c])) {\n\tm2exp = !m2exp;\n\n      } else if(!strcmp(\"--m2diff\", argv&#91;c])) {\n\tm2diff = !m2diff;\n\n      } else if(!strcmp(\"--m2digits\", argv&#91;c])) {\n\tm2digits = !m2digits;\n\t\n      } else if(!strcmp(\"--m2digdiff\", argv&#91;c])) {\n\tm2digdiff = !m2digdiff;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\",procname,argv&#91;c]);\n\thelp = 1;\n\n      }\n    }\n  } \/\/ end of for(c = 1; c &lt; argc; c++)\n\n#ifdef DEBUG17\n  fprintf(stdout,\"multiple1:%d\", multiple1);\n  fprintf(stdout,\", m1exp:%d\", m1exp);\n  fprintf(stdout,\", m1diff:%d\", m1diff);\n  fprintf(stdout,\"\\n\");\n#endif\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\",procname);\n    fprintf(stderr,\" &#91;-]\");\n    fprintf(stderr,\"\/&#91;filename]\");\n    fprintf(stderr,\" &#91;--verbose]\");\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--all]\");\n    fprintf(stderr,\" &#91;--ctrl]\");\n    fprintf(stderr,\" &#91;--chars]\");\n    fprintf(stderr,\" &#91;--cdiff]\");\n    fprintf(stderr,\" &#91;--multiple1]\");\n    fprintf(stderr,\" &#91;--m1exp]\");\n    fprintf(stderr,\" &#91;--m1diff]\");\n    fprintf(stderr,\" &#91;--m1digits]\");\n    fprintf(stderr,\" &#91;--m1digdiff]\");\n    fprintf(stderr,\" &#91;--multiple2]\");\n    fprintf(stderr,\" &#91;--m2exp]\");\n    fprintf(stderr,\" &#91;--m2diff]\");\n    fprintf(stderr,\" &#91;--m2digits]\");\n    fprintf(stderr,\" &#91;--m2digdiff]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  \/\/ open needed random file\n  \n  if(!strcmp(filename,\"-\")) {\n    fp1 = stdin;\n  } else if((fp1 = fopen(filename, \"r\")) == NULL) {\n    fprintf(stderr,\"%s: fopen: cannot open file %s\", procname, filename);\n    exit(2);\n  }\n  \n#define MAXCOUNT 256\n\n  long int charcounts&#91;MAXCOUNT];\n  \n  for(c = 0; c &lt; MAXCOUNT; c++)\n    charcounts&#91;c] = 0;\n  \n#define MAX 1024\n  \n  int currentchar = 0;\n  unsigned char prevchars&#91;MAX];\n  unsigned long int m1counts&#91;MAX];\n  unsigned long int m2counts&#91;MAX];\n  \n  for(c = 0; c &lt; MAX; c++) {\n    prevchars&#91;c] = 0;\n    m1counts&#91;c] = 0;\n    m2counts&#91;c] = 0;    \n  }\n\n  unsigned long int singles = 0;\n\n  int ch, prevch;\n  unsigned long m2length;\n  \n  first = 1;\n\n  unsigned char buffer&#91;1024];\n  unsigned char *ifile = NULL;\n  unsigned long long ifilelength = 0;\n  \n  \/\/ read input file to buffer\n\n  while(fgets(buffer,sizeof(buffer),fp1)!=NULL) {\n    if(verbose) {\n      fprintf(stdout,\"%s\",buffer);\n    }\n\n    int bytes = 0;\n\n    if(ifile != NULL)\n      bytes += strlen(ifile);\n    bytes += strlen(buffer);\n    bytes += 1;\n\n    if(ifilelength &lt; bytes) {\n      ifilelength = bytes;\n      if((ifile = realloc(ifile, ifilelength)) == NULL) {\n\tfprintf(stderr,\"%s:\",procname);\n\tfprintf(stderr,\" realloc(): cannot allocate memory\");\n\tfprintf(stderr,\", %lld bytes\",ifilelength);\n\tfprintf(stderr,\"\\n\");\n\texit(2);\n      }\n    }\n    strcat(ifile, buffer);\n  }\n\n  if(verbose)\n    fflush(stdout);\n  \n  unsigned char *p;\n\n  p = ifile;\n\n  while((ch = *p++) != '\\0') {\n\n    \/\/ calculate character counts for\n    \/\/ character statistics\n    \n    charcounts&#91;ch]++;\n\n    if(ch &lt;= 0x20) \/\/ ctrl or space, skip\n      continue;\n\n    singles++;\n  } \/\/ end of for(c = 0; c &lt; ifilelength; c++)\n\n  if(singles == 0) {\n    fprintf(stderr,\"%s: no data\\n\", procname);\n    exit(2);\n  }\n\n  int charnum&#91;MAXCOUNT];\n  int charascii&#91;MAXCOUNT];\n\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    charnum&#91;c] = -1;\n    charascii&#91;c] = -1;\n  }\n\n  int num = 0;\n  \n  for(c = 0; c &lt; MAXCOUNT; c++) {\n\n    if(c &lt;= 0x20) \/\/ ctrl or space, skip\n      continue;\n\n    if(charcounts&#91;c] != 0) {\n      charnum&#91;c] = num;\n      charascii&#91;num] = c;\n      num++;\n    }      \n  }\n\n#define aDEBUG25 2\n\n#ifdef DEBUG25\n\n  fprintf(stdout,\"charnum  \");\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    if(charnum&#91;c] != -1)\n      fprintf(stdout,\" %d:%d\", c, charnum&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  fprintf(stdout,\"charascii\");\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    if(charascii&#91;c] != -1)\n      fprintf(stdout,\" %d:%d\", c, charascii&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n\n#endif\n  \n  unsigned long int count = 0, ctotal = 0;\n\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    if(charcounts&#91;c] &gt; 0) {\n  \n      if(c &lt;= 0x20) \/\/ ctrl or space, skip\n\tcontinue;\n\n      ctotal += charcounts&#91;c];\n      count++;\n\n    } \/\/ if(charcounts&#91;c] &gt; 0)\n  } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n\n  long m1multiplecounts&#91;MAX]&#91;count];\n  long m2multiplecounts&#91;MAX]&#91;count];\n\n  for(c = 0; c &lt; MAX; c++) {\n    for(d = 0; d &lt; count; d++) {\n      m1multiplecounts&#91;c]&#91;d] = 0;\n      m2multiplecounts&#91;c]&#91;d] = 0;\n    }\n  }\n\n  p = ifile;\n  first = 1;\n  m2length = 0;\n  \n  while((ch = *p++) != '\\0') {\n\n    if(ch &lt;= 0x20) \/\/ ctrl or space, skip\n      continue;\n\n    \/\/ calculate m1 multiple\n    \/\/ counts\n    \n    prevchars&#91;currentchar] = ch;\n    \n    for(c = 0; c &lt; MAX; c++) {\n\n      d = currentchar - c;\n      if(d &lt; 0)\n\td += MAX;\n\n      if(ch != prevchars&#91;d])\n\tbreak;\n\n      m1counts&#91;c]++; \n      m1multiplecounts&#91;c]&#91;charnum&#91;ch]]++;\n    }\n\n    if(++currentchar &gt;= MAX)\n      currentchar -= MAX;\n    \n    \/\/ calculate m2 multiple\n    \/\/ counts\n    \n    if(first) {\n      prevch = ch;\n      m2length = 1;\n      first = 0;\n    } else {\n      if(prevch == ch) {\n\tm2length++;\n      } else {\n\tm2counts&#91;m2length - 1]++;\n\tm2multiplecounts&#91;m2length - 1]&#91;charnum&#91;prevch]]++;\n\tm2length = 1;\n\tprevch = ch;\n      }\n    }\n  } \/\/ end of for(c = 0; c &lt; ifilelength; c++)\n  \n  if(m2length &gt; 0) {\n    m2counts&#91;m2length - 1]++; \/\/ add last m2 multiple\n    m2multiplecounts&#91;m2length - 1]&#91;charnum&#91;prevch]]++;\n  }\n\n#ifdef DEBUG46\n  for(c = 0; c &lt; MAX; c++) {\n    for(d = 0; d &lt; count; d++) {\n      fprintf(stdout,\" %lu\",m2multiplecounts&#91;c]&#91;d]);\n    }\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  \/\/ print control line if needed\n  \n  if(ctrl) {\n    char *ctrlchars&#91;] = {\n      \"NUL\", \"0x01\", \"0x02\", \"0x03\", \"0x04\", \"0x05\", \"0x06\", \"BEL\", \"BS\",\n      \"0x09\", \"LF\", \"0x0b\", \"0x0c\", \"CR\", \"0x0e\", \"0x0f\",\n      \"0x10\", \"0x11\", \"0x12\", \"0x13\", \"0x14\", \"0x15\", \"0x16\", \"0x17\", \"0x18\",\n      \"0x19\", \"0x1a\", \"ESC\", \"0x1c\", \"0x1d\", \"0x1e\", \"0x1f\",\n      \"space\"\n    };\n    \n    fprintf(stdout,\"ctrl      \");\n    first = 1;\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &gt; 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%s\", ctrlchars&#91;c]);\n\t\n\tfprintf(stdout,\":%lu\", charcounts&#91;c]);\n\t\n\tfirst = 0;\n      } \/\/ end of if(charcounts&#91;c] &gt; 0)\n    }\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(ctrl)\n\n  \/\/ calculate average\n\n  unsigned long int average;\n  \n  average = ctotal \/ count;\n  \n  long int min;\n  long int max;\n  \n  min = LONG_MAX;\n  max = LONG_MIN;\n  \n  \/\/ print character counts if needed\n  \n  if(chars) {\n    long int allchars;\n\n    fprintf(stdout,\"chars     \");\n    first = 1;\n    allchars = 0;\n\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &lt;= 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%02x\", c);\n\t\n\tfprintf(stdout,\":%lu\", charcounts&#91;c]);\n\n\tallchars += charcounts&#91;c];\n\n\tif(min &gt; charcounts&#91;c])\n\t  min = charcounts&#91;c];\n\tif(max &lt; charcounts&#91;c])\n\t  max = charcounts&#91;c];\n\n\tfirst = 0;\n      }\n    }\n    fprintf(stdout,\", total:%ld\", allchars);\n    fprintf(stdout,\", count:%ld\", count);\n    fprintf(stdout,\", average:%ld\", average);\n    fprintf(stdout,\", total:%ld\", allchars);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(chars)\n\n  \/\/ calculate and print character\n  \/\/ differences\n\n  min = LONG_MAX;\n  max = LONG_MIN;\n  \n  if(cdiff) {\n    fprintf(stdout,\"cdiff     \");\n\n    long int chardiff = 0;\n    long int chardifftotal = 0;\n    \n    first = 1;\n\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n\n      if(c &lt;= 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%02x\", c);\n\t\n\tfprintf(stdout,\":%ld\", average - charcounts&#91;c]);\n\n\tchardiff = (average - charcounts&#91;c]);\n\n\tchardifftotal += chardiff;\n\n\tif(min &gt; chardiff)\n\t  min = chardiff;\n\tif(max &lt; chardiff)\n\t  max = chardiff;\n\n\tfirst = 0;\n      } \/\/ end of if(charcounts&#91;c] &gt; 0)\n    } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n    \n    fprintf(stdout,\", total:%ld\", chardifftotal);\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(cdiff)\n  \n  \/\/ print statistics on m1 multiples,\n  \/\/ multiple1, m1exp and m1diff\n\n  for(int e = 0; e &lt; 3; e++) {\n    if(e==0) {\n      if(!multiple1)\n\tcontinue;\n      fprintf(stdout, \"multiple1 \");\n    } else if(e==1) {\n      if(!m1exp)\n\tcontinue;\n      fprintf(stdout, \"m1exp     \");\n    } else {\n      if(!m1diff)\n\tcontinue;\n      fprintf(stdout, \"m1diff    \");\n    }\n    long int total = 0;\n    long int expect = singles;\n    first = 1;\n    for(c = 0; c &lt; MAX; c++) {\n      if(m1counts&#91;c] &gt; 0) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tfprintfmultipletype(stdout, c);\n\t\n\tlong int temp;\n\t\n\tif(e == 0)\n\t  temp = m1counts&#91;c];\n\telse if(e == 1)\n\t  temp = expect;\n\telse\n\t  temp = expect - m1counts&#91;c];\n\t\n\ttotal += temp;\n\t\n\tfprintf(stdout,\":%ld\", temp);\n      }\n      expect \/= count;\n      first = 0;\n    }\n    fprintf(stdout,\", total:%ld\", total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of for(int e = 0; e &lt; 3; e++)\n\n  \/\/ print statistics on m1 multiples,\n  \/\/ m1digits and m1digdiff\n  \n  long int m1expected = singles;\n\n  for(c = 0; c &lt; MAX; c++) {\n    int print = 0;\n    for(d = 0; d &lt; count; d++) {\n      if(m1multiplecounts&#91;c]&#91;d] != 0)\n\tprint = 1;\n    }\n    if(print) {\n      for(int e = 0; e &lt; 2; e++) { \/\/ 0 -&gt; digits, 1 -&gt; diff\n\tif(e==0) {\n\t  if(!m1digits)\n\t    continue;\n\t  fprintf(stdout,\"m1digits  \");\n\t} else if(e==1) {\n\t  if(!m1digdiff)\n\t    continue;\n\t  fprintf(stdout,\"m1digdiff \");\n\t}\n\tmin = LONG_MAX;\n\tmax = LONG_MIN;\n\n\tfprintfmultipletype(stdout, c);\n\t\n\tunsigned long total = 0;\n\t\n\tfirst = 1;\n\t\n\tfor(d = 0; d &lt; count; d++) {\n\t  if(m1multiplecounts&#91;c]&#91;d] != 0) {\n\t    unsigned char ch = charascii&#91;d];\n\t    if(!first)\n\t      fprintf(stdout,\",\");\t    \n\t    fprintf(stdout,\" \");\n\t    if(isprint(ch) &amp;&amp; ch &gt; ' ')\n\t      fprintf(stdout,\"%c\", ch);\n\t    else\n\t      fprintf(stdout,\"%02x\", ch);\n\n\t    long temp;\n\t    if(e == 0)\n\t      temp = m1multiplecounts&#91;c]&#91;d];\n\t    else if(e == 1)\n\t      temp = m1expected \/ count - m1multiplecounts&#91;c]&#91;d];\n\t    fprintf(stdout,\":%ld\", temp);\n\t    total += temp;\n\t    first = 0;\n\n\t    if(min &gt; temp)\n\t      min = temp;\n\t    if(max &lt; temp)\n\t      max = temp;\n\t  }\n\t}\n\tif(!first) {\n\t  if(e == 0)\n\t    fprintf(stdout,\", dexp:%ld\", m1expected \/ count);\n\t  fprintf(stdout,\", total:%ld\", total);\n\t  if(e == 0)\n\t    fprintf(stdout,\", texp:%ld\", m1expected);\n\t  fprintf(stdout,\", min:%ld\", min);\n\t  fprintf(stdout,\", max:%ld\", max);\n\t}\n\tfprintf(stdout,\"\\n\");\n      } \/\/ end of for(int e = 0; e &lt; 2; e++)\n    }\n    m1expected \/= count;\n  }\n\n  unsigned long int m2expects&#91;MAX];\n  double base;\n  \n  for(c = 0; c &lt; MAX; c++) {\n    m2expects&#91;c] = 0;\n  }\n    \n  base = (((double)count - 1) \/ count)  * (((double)count - 1) \/ count);\n  for(c = 0; c &lt; MAX; c++) {\n    if(base * ctotal &gt; 0) {\n      m2expects&#91;c] = (unsigned long int) (base * ctotal);\n      base *= ((double)1 \/ count);\n    }\n  }\n  \n  \/\/ print statistics on m2 multiples\n  \/\/ multiple1 m2exp and m2diff\n  \n  for(int e = 0; e &lt; 3; e++) {\n    if(e==0) {\n      if(!multiple2)\n\tcontinue;\n      fprintf(stdout,\"multiple2 \");\n    } else if(e==1) {\n      if(!m2exp)\n\tcontinue;\n      fprintf(stdout,\"m2exp     \");\n    } else {\n      if(!m2diff)\n\tcontinue;\n      fprintf(stdout,\"m2diff    \");\n    }\n    \n    unsigned long int total = 0;\n    \n    first = 1;\n    \n    for(c = 0; c &lt; MAX; c++) {\n      if(m2counts&#91;c] &gt; 0) {\n\tif(first == 0)\n\t  fprintf(stdout,\", \");\n\n\tfprintfmultipletype(stdout, c);\n\t\n\tlong int temp;\n\t\n\tif(e == 0) {\n\t  temp = m2counts&#91;c];\n\t  \/\/total += temp * (c + 1);\n\t} else if(e == 1) {\n\t  temp = m2expects&#91;c];\n\t  \/\/total += temp * (c + 1);\n\t} else {\n\t  temp = m2expects&#91;c] - m2counts&#91;c];\n\t  \/\/total += temp;\n\t}\t\n\tfprintf(stdout,\":%ld\", temp);\n\ttotal += temp * (c + 1);\n\tfirst = 0;\n      }\n    } \/\/ end of for(c = 1; c &lt; MAX; c++)\n    \n    fprintf(stdout,\", total:%ld\",total);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end if for(int e = 0; e &lt; 3; e++)\n\n  \/\/ print statistics on m2 multiples\n  \/\/ m2digits and m2digdiff\n  \n  double m2expectedbase = (((double)count - 1) \/ count)  * (((double)count - 1) \/ count);\n\n  for(c = 0; c &lt; MAX; c++) {\n    int print = 0;\n    for(d = 0; d &lt; count; d++) {\n      if(m2multiplecounts&#91;c]&#91;d] != 0)\n\tprint = 1;\n    }\n    if(print) {\n      unsigned long m2exp = m2expectedbase * ctotal;\n      for(int e = 0; e &lt; 2; e++) { \/\/ 0 -&gt; digits, 1 -&gt; diff\n\tif(e==0) {\n\t  if(!m2digits)\n\t    continue;\n\t  fprintf(stdout,\"m2digits  \");\n\t} else {\n\t  if(!m2digdiff)\n\t    continue;\n\t  fprintf(stdout,\"m2digdiff \");\n\t}\n\tmin = LONG_MAX;\n\tmax = LONG_MIN;\n\n\tfprintfmultipletype(stdout, c);\n\t\n\tfirst = 1;\n\t\n\tlong int total = 0;\n\t\n\tfor(d = 0; d &lt; count; d++) {\n\t  if(m2multiplecounts&#91;c]&#91;d] != 0) {\n\t    unsigned char ch = charascii&#91;d];\n\t    if(!first)\n\t      fprintf(stdout,\",\");\n\t    fprintf(stdout,\" \");\n\t    if(isprint(ch) &amp;&amp; ch &gt; ' ')\n\t      fprintf(stdout,\"%c\", ch);\n\t    else\n\t      fprintf(stdout,\"%02x\", ch);\n\n\t    long temp;\n\t    if(e==0)\n\t      temp = m2multiplecounts&#91;c]&#91;d];\n\t    else\n\t      temp = m2exp \/ count - m2multiplecounts&#91;c]&#91;d];\n\n\t    fprintf(stdout,\":%ld\", temp);\n\t    total += temp;\n\n\t    if(min &gt; temp)\n\t      min = temp;\n\t    if(max &lt; temp)\n\t      max = temp;\n\n\t    first = 0;\n\t  }\n\t}\n\tif(!first) {\t\n\t  if(e == 0)\n\t    fprintf(stdout,\", dexp:%lu\", (unsigned long) m2exp \/ count);\n\t  fprintf(stdout,\", total:%ld\", total);\n\t  if(e == 0)\n\t    fprintf(stdout,\", texp:%lu\", (unsigned long) m2exp);\n\t  fprintf(stdout,\", min:%ld\", min);\n\t  fprintf(stdout,\", max:%ld\", max);\n\t}\n\tfprintf(stdout,\"\\n\");\n      } \/\/ end of for(int e = 0; e &lt; 2; e++)\n      m2expectedbase *= ((double)1 \/ count);\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Nelj\u00e4s ohjelma jonka kirjoitin tekee edelleen tilastoja satunnaisuudesta: t\u00e4ll\u00e4 kertaa tilastoidaan newressu tulosteen sanoja (words), eli v\u00e4lily\u00f6nneill\u00e4 eroteltuja satunnaismerkkisarjoja. Seuraavassa raportissa sanan pituus on 1, jolloin tuotettu raportti on vastaa aiemmin laskettua chars rivi\u00e4. T\u00e4ll\u00e4 voi debukata words toimintoa. Raportin &#8211;set toiminnolla voidaan tulostaa tietue, johon words rakenne lasketaan (vrt terttu).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --bin -s1 --lineno --space -l1000| .\/newressutest9 --set\nset       '0' = \"18112\", '1' = \"17888\"\nctrl      LF:1000, space:35000\nchars     0:18112, 1:17888, words:2, total:36000, average:18000, min:17888, max:18112\ncdiff     0:-112, 1:112, total:0, min:-112, max:112\nwords     0:18112, 1:17888, words:2, total:36000, average:18000, min:17888, max:18112\nwdiff     0:-112, 1:112, total:0, min:-112, max:112\n$ <\/code><\/pre>\n\n\n\n<p>Varsinainen toiminta on kuitenkin siin\u00e4 ett\u00e4 verrataan useampimerkkisi\u00e4 sanoja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --bin -s2 --lineno --space -l1000 | .\/newressutest9 --set\nset       '00' = \"6061\", '01' = \"5916\", '10' = \"6009\", '11' = \"6014\"\nctrl      LF:1000, space:23000\nchars     0:24047, 1:23953, words:2, total:48000, average:24000, min:23953, max:24047\ncdiff     0:-47, 1:47, total:0, min:-47, max:47\nwords     00:6061, 01:5916, 10:6009, 11:6014, words:4, total:24000, average:6000, min:5916, max:6061\nwdiff     00:-61, 01:84, 10:-9, 11:-14, total:0, min:-61, max:84\n$ <\/code><\/pre>\n\n\n\n<p>Edellisess\u00e4 on listattu bin\u00e4\u00e4riset 2 bittiset sanat, jotka ovat 00, 01, 10 ja 11. Koska vaihtoehtoja on nelj\u00e4, yhden yhdistelm\u00e4n todenn\u00e4k\u00f6isyys on 1\/4 eli 25%.<\/p>\n\n\n\n<p>Listaan poikkeuksellisesti ensimm\u00e4isen\u00e4 newressutest9:n tietorakenteen hallinnan, koska se on tavallaan erillinen kokonaisuus. En kuitenkaan viel\u00e4 laittanut sit\u00e4 omaan tiedostoon:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *db5_set = NULL;\n\nunsigned char *db5_get_set()\n{\n  return(db5_set);\n}\n\nvoid db5_skipwhite(unsigned char **p)\n{\n  while(isblank(**p))\n    (*p)++;\n}\n\nvoid db5_get_element(unsigned int *namelen, unsigned char **name, unsigned int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db5_skipwhite(&amp;p);\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *name = p;\n    *namelen = 0;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  }\n\n  db5_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db5_skipwhite(&amp;p);\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *value = p;\n    *valuelen = 0;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  }\n\n  db5_skipwhite(&amp;p);\n\n  *p2 = p;\n}\n\n#define aDEBUG9 2\n#define aDEBUG10 2\n#define aDEBUG11 2\n\nint db5_get(unsigned char *name, int valuesize, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen = strlen(name);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** get\\n\");\n#endif\n  \n  value&#91;0] = '\\0';\n\n  if(db5_set != NULL) {\n\n    firstelement = 1;\n    p = db5_set;\n\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n      \n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n#ifdef DEBUG9\n      fprintf(stdout,\"name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(db5_set != NULL)\n  return(retval);\n}\n\n#define SORTED 2\n\nvoid db5_put(unsigned char *name, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  unsigned int namelen = strlen(name);\n  unsigned int valuelen = strlen(value);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** put\\n\");\n#endif\n  \n  firstelement = 1;\n  lastelement = 0;\n\n  if(db5_set != NULL) {\n\n    p = db5_set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n\n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n#ifdef DEBUG9\n      fprintf(stdout,\"name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } else { \/\/ else of if(db5_set != NULL)\n\n    lastelement = 1;\n    firstelement = 1;\n\n  } \/\/ end of if(db5_set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n\n  if((firstelement &amp;&amp; found) || \/\/ first and existing\n     (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n    elementfmt = \"'%s' = \\\"%s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n  else if(firstelement) \/\/ first and not existing element\n    elementfmt = \"'%s' = \\\"%s\\\", \"; \/\/ --&gt; comma in the end (first new)\n  else\n    elementfmt = \", '%s' = \\\"%s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n\n  \/\/ print element\n\n  count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  if(elementsize &lt; count) {\n    elementsize = count;\n    if((element = realloc(element, elementsize)) == NULL) {\n      fprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n    count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  }\n#ifdef DEBUG22\n  fprintf(stdout,\", set: %s\", db5_set);\n  fprintf(stdout,\"\\n\");\n#endif\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(db5_set != NULL) {\n    count += strlen(db5_set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout, \"old length:%ld %s\\n\", oldcount, db5_set);\n    fflush(stdout);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempdb5_set = db5_set;\n    if((db5_set = realloc(db5_set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = db5_set + (thiselement - tempdb5_set);\n    if(nextelement != NULL)\n      nextelement = db5_set + (nextelement - tempdb5_set);\n\n    if(tempdb5_set == NULL)\n      db5_set&#91;0] = '\\0';\n  }\n\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = db5_set + strlen(db5_set);\n  if(nextelement == NULL)\n    nextelement = db5_set + strlen(db5_set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout,\"new length:%ld %s\\n\", count, db5_set);\n    fflush(stdout);\n  }\n#endif  \n  \n#ifdef DEBUG10\n  fprintf(stdout,\", set      %s(%ld)\", db5_set, strlen(db5_set));\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Edellinen koodi listaa db5_put():in db5_get():in, joilla voisi olla potentiaalia my\u00f6s tertun ytimeen.<\/p>\n\n\n\n<p>Seuraavassa lista, josta n\u00e4kee selvemmin datarakenteen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat newressudb5test.sh\n#!\/bin\/bash\nfor ((c=0;c&lt;5;c++)); do .\/newressu --single --bin -s1 --spaces $@ --lineno -l1000 | .\/newressutest9 --all; done;\nfor ((c=0;c&lt;5;c++)); do .\/newressu --single --oct -s1 --spaces $@ --lineno -l1000 | .\/newressutest9 --all; done;\nfor ((c=0;c&lt;5;c++)); do .\/newressu --single --dec -s1 --spaces $@ --lineno -l1000 | .\/newressutest9 --all; done;\nfor ((c=0;c&lt;5;c++)); do .\/newressu --single --hex -s1 --spaces $@ --lineno -l1000 | .\/newressutest9 --all; done;\n$ .\/newressudb5test.sh\nset       '0' = \"17983\", '1' = \"18017\"\nset       '0' = \"17935\", '1' = \"18065\"\nset       '0' = \"17851\", '1' = \"18149\"\nset       '0' = \"18034\", '1' = \"17966\"\nset       '0' = \"18086\", '1' = \"17914\"\nset       '0' = \"4507\", '1' = \"4508\", '2' = \"4524\", '3' = \"4466\", '4' = \"4438\", '5' = \"4542\", '6' = \"4538\", '7' = \"4477\"\nset       '0' = \"4535\", '1' = \"4541\", '2' = \"4467\", '3' = \"4589\", '4' = \"4449\", '5' = \"4510\", '6' = \"4390\", '7' = \"4519\"\nset       '0' = \"4528\", '1' = \"4502\", '2' = \"4445\", '3' = \"4507\", '4' = \"4574\", '5' = \"4444\", '6' = \"4516\", '7' = \"4484\"\nset       '0' = \"4442\", '1' = \"4493\", '2' = \"4505\", '3' = \"4394\", '4' = \"4600\", '5' = \"4531\", '6' = \"4494\", '7' = \"4541\"\nset       '0' = \"4569\", '1' = \"4346\", '2' = \"4472\", '3' = \"4464\", '4' = \"4447\", '5' = \"4585\", '6' = \"4551\", '7' = \"4566\"\nset       '0' = \"3572\", '1' = \"3571\", '2' = \"3573\", '3' = \"3633\", '4' = \"3596\", '5' = \"3616\", '6' = \"3743\", '7' = \"3492\", '8' = \"3622\", '9' = \"3582\"\nset       '0' = \"3620\", '1' = \"3650\", '2' = \"3567\", '3' = \"3610\", '4' = \"3561\", '5' = \"3622\", '6' = \"3698\", '7' = \"3556\", '8' = \"3553\", '9' = \"3563\"\nset       '0' = \"3598\", '1' = \"3616\", '2' = \"3594\", '3' = \"3732\", '4' = \"3587\", '5' = \"3603\", '6' = \"3511\", '7' = \"3598\", '8' = \"3562\", '9' = \"3599\"\nset       '0' = \"3577\", '1' = \"3575\", '2' = \"3640\", '3' = \"3568\", '4' = \"3648\", '5' = \"3591\", '6' = \"3570\", '7' = \"3577\", '8' = \"3682\", '9' = \"3572\"\nset       '0' = \"3584\", '1' = \"3643\", '2' = \"3621\", '3' = \"3696\", '4' = \"3522\", '5' = \"3698\", '6' = \"3526\", '7' = \"3611\", '8' = \"3630\", '9' = \"3469\"\nset       '0' = \"2344\", '1' = \"2323\", '2' = \"2156\", '3' = \"2296\", '4' = \"2314\", '5' = \"2249\", '6' = \"2275\", '7' = \"2220\", '8' = \"2289\", '9' = \"2202\", 'a' = \"2227\", 'b' = \"2262\", 'c' = \"2240\", 'd' = \"2177\", 'e' = \"2211\", 'f' = \"2215\"\nset       '0' = \"2235\", '1' = \"2151\", '2' = \"2361\", '3' = \"2218\", '4' = \"2214\", '5' = \"2218\", '6' = \"2266\", '7' = \"2251\", '8' = \"2281\", '9' = \"2192\", 'a' = \"2227\", 'b' = \"2313\", 'c' = \"2259\", 'd' = \"2236\", 'e' = \"2337\", 'f' = \"2241\"\nset       '0' = \"2209\", '1' = \"2197\", '2' = \"2289\", '3' = \"2343\", '4' = \"2260\", '5' = \"2253\", '6' = \"2298\", '7' = \"2195\", '8' = \"2224\", '9' = \"2197\", 'a' = \"2205\", 'b' = \"2308\", 'c' = \"2254\", 'd' = \"2221\", 'e' = \"2266\", 'f' = \"2281\"\nset       '0' = \"2234\", '1' = \"2270\", '2' = \"2310\", '3' = \"2151\", '4' = \"2271\", '5' = \"2259\", '6' = \"2295\", '7' = \"2199\", '8' = \"2318\", '9' = \"2207\", 'a' = \"2230\", 'b' = \"2206\", 'c' = \"2275\", 'd' = \"2275\", 'e' = \"2253\", 'f' = \"2247\"\nset       '0' = \"2314\", '1' = \"2290\", '2' = \"2202\", '3' = \"2300\", '4' = \"2133\", '5' = \"2218\", '6' = \"2229\", '7' = \"2292\", '8' = \"2208\", '9' = \"2251\", 'a' = \"2224\", 'b' = \"2239\", 'c' = \"2289\", 'd' = \"2248\", 'e' = \"2279\", 'f' = \"2284\"\n$ <\/code><\/pre>\n\n\n\n<p>Listan alussa on laskettu bin\u00e4\u00e4ri merkkej\u00e4 (5 rivi\u00e4), seuraavaksi oktaalimerkkej\u00e4, desimaalimerkkej\u00e4 ja heksamerkkej\u00e4.<\/p>\n\n\n\n<p>Datarakenteessa on t\u00e4ss\u00e4 sanat (words) ja samanlaisten sanojen lukum\u00e4\u00e4r\u00e4, mutta kun sanan tilalle laittaa kent\u00e4n nimen ja lukum\u00e4\u00e4r\u00e4n tilalle kent\u00e4n arvon, voidaan alkaa miettim\u00e4\u00e4n esimerkiksi appia tilaus ja siihen liittyvi\u00e4 kenttia ja tiedostoja (tilaus, asiakas, tilausrivit, tuote, asiakasmyynti, toimitus jne.). Edit: Tietenkin ilman kovakoodattuja sarakkeita, tauluja ja appeja.<\/p>\n\n\n\n<p>Ja koodi kokonaisuudessaan: (huomaa ett\u00e4 ohjelmassa on TEST80 kappale, joka ristiintarkistaa chars rivin ja words rivin luvut, se on nyt p\u00e4\u00e4ll\u00e4) <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;limits.h&gt;\n#include &lt;math.h&gt;\n\nstatic unsigned char *procname;\nstatic unsigned char *programname = \"newressutest9 version 0.4 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nunsigned char *db5_set = NULL;\n\nunsigned char *db5_get_set()\n{\n  return(db5_set);\n}\n\nvoid db5_skipwhite(unsigned char **p)\n{\n  while(isblank(**p))\n    (*p)++;\n}\n\nvoid db5_get_element(unsigned int *namelen, unsigned char **name, unsigned int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db5_skipwhite(&amp;p);\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *name = p;\n    *namelen = 0;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  }\n\n  db5_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db5_skipwhite(&amp;p);\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *value = p;\n    *valuelen = 0;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  }\n\n  db5_skipwhite(&amp;p);\n\n  *p2 = p;\n}\n\n#define aDEBUG9 2\n#define aDEBUG10 2\n#define aDEBUG11 2\n\nint db5_get(unsigned char *name, int valuesize, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen = strlen(name);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** get\\n\");\n#endif\n  \n  value&#91;0] = '\\0';\n\n  if(db5_set != NULL) {\n\n    firstelement = 1;\n    p = db5_set;\n\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n      \n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n#ifdef DEBUG9\n      fprintf(stdout,\"get name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      db5_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(db5_set != NULL)\n  return(retval);\n}\n\n#define SORTED 2\n\nvoid db5_put(unsigned char *name, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  unsigned int namelen = strlen(name);\n  unsigned int valuelen = strlen(value);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** put\\n\");\n#endif\n  \n  firstelement = 1;\n  lastelement = 0;\n\n  if(db5_set != NULL) {\n\n    p = db5_set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n\n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db5_skipwhite(&amp;p);\n      \n#ifdef DEBUG9\n      fprintf(stdout,\"put name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } else { \/\/ else of if(db5_set != NULL)\n\n    lastelement = 1;\n    firstelement = 1;\n\n  } \/\/ end of if(db5_set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n\n  if((firstelement &amp;&amp; found) || \/\/ first and existing\n     (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n    elementfmt = \"'%s' = \\\"%s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n  else if(firstelement) \/\/ first and not existing element\n    elementfmt = \"'%s' = \\\"%s\\\", \"; \/\/ --&gt; comma in the end (first new)\n  else\n    elementfmt = \", '%s' = \\\"%s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n\n  \/\/ print element\n\n  count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  if(elementsize &lt; count) {\n    elementsize = count;\n    if((element = realloc(element, elementsize)) == NULL) {\n      fprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n    count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  }\n#ifdef DEBUG22\n  fprintf(stdout,\", set: %s\", db5_set);\n  fprintf(stdout,\"\\n\");\n#endif\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(db5_set != NULL) {\n    count += strlen(db5_set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout, \"old length:%ld %s\\n\", oldcount, db5_set);\n    fflush(stdout);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempdb5_set = db5_set;\n    if((db5_set = realloc(db5_set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = db5_set + (thiselement - tempdb5_set);\n    if(nextelement != NULL)\n      nextelement = db5_set + (nextelement - tempdb5_set);\n\n    if(tempdb5_set == NULL)\n      db5_set&#91;0] = '\\0';\n  }\n\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = db5_set + strlen(db5_set);\n  if(nextelement == NULL)\n    nextelement = db5_set + strlen(db5_set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout,\"new length:%ld %s\\n\", count, db5_set);\n    fflush(stdout);\n  }\n#endif  \n  \n#ifdef DEBUG10\n  fprintf(stdout,\", set      %s(%ld)\", db5_set, strlen(db5_set));\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}\n\n#define aDEBUG34 2\n\nvoid increment(unsigned char *name)\n{\n  unsigned long long count;\n  unsigned char buffer&#91;32];\n\n#ifdef DEBUG9\n  fprintf(stdout, \"********** increment\\n\");\n#endif\n\n  count = 0;\n  if(db5_get(name, sizeof(buffer), buffer) != 0)\n    count = atoll(buffer);\n  count++;\n  sprintf(buffer,\"%lld\", count);\n  db5_put(name, buffer);\n#ifdef DEBUG34\n  fprintf(stdout, \", '%s', \\\"%s\\\"\",name, buffer);\n  fflush(stdout);\n#endif\n}\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, first;\n  int verbose = 0, help = 0, all = 1, set = 0,\n    ctrl = 1, chars = 1, cdiff = 1,\n    words = 1, wdiff = 1;\n  char filename&#91;128] = \"-\"; \/\/ default stdin\n  \n  FILE *fp1;\n  \n  procname = argv&#91;0];\n\n#define aTEST39 2 \/\/ default is off\n  \n#ifdef TEST39\n\n  \/\/ tests for earlier db5 routines\n  \n  db5_set = \"'kala' = \\\"kele\\\", 'kala2' = \\\"kele2\\\", 'kala3' = \\\"kele3\\\"\";\n\n  unsigned int valuelen = 1024, valuelen2;\n  unsigned char value&#91;1024];\n\n  \/\/ dbget\n  \n  fprintf(stdout,\"db5\\n\");\n  fflush(stdout);\n  db5_get(\"kala\", valuelen, value);\n  valuelen2 = strlen(value);\n  fprintf(stdout,\"*value:%.*s(%d)\\n\",\n\t  valuelen2, value, valuelen2);\n  fflush(stdout);\n  db5_get(\"kala2\", valuelen, value);\n  valuelen2 = strlen(value);\n  fprintf(stdout,\"*value:%.*s(%d)\\n\",\n\t  valuelen2, value, valuelen2);\n  fflush(stdout);\n  db5_get(\"kala3\", valuelen, value);\n  valuelen2 = strlen(value);\n  fprintf(stdout,\"*value:%.*s(%d)\\n\",\n\t  valuelen2, value, valuelen2);\n  fflush(stdout);\n\n  \/\/ dbput and sorting\n  \n  db5_set = NULL;\n  db5_put(\"kala\", \"kele\");\n  db5_put(\"kala1\", \"kele1\");\n  db5_put(\"kala2\", \"kele2\");\n  db5_put(\"kala21\", \"kele211111\");\n  db5_put(\"kala3\", \"kele3\");\n  db5_put(\"kala2\", \"kele2b\");\n  db5_put(\"kala21\", \"kele21\");\n  db5_put(\"kala21\", \"kele21111\");\n\n  \/\/ test increment\n  \n  free(db5_set);\n  db5_set = NULL;\n  increment(\"a\");\n  increment(\"b\");\n  increment(\"b\");\n  increment(\"c\");\n  increment(\"c\");\n  increment(\"c\");\n\n  \/\/ utf8 characters\n  \n  free(db5_set);\n  db5_set = NULL;\n  increment(\"\u2680\");  \n  increment(\"\u2681\");  \n  increment(\"\u2682\");  \n  increment(\"\u2683\");  \n  increment(\"\u2684\");  \n  increment(\"\u2685\");  \n\n  \/\/ sorting with different lengths of name\n  \n  free(db5_set);\n  db5_set = NULL;\n  db5_put(\"ccccc\", \"ccccc\");\n  db5_put(\"a\", \"a\");\n  db5_put(\"bbbb\", \"bbbb\");\n  db5_put(\"b\", \"b\");\n  db5_put(\"cccc\", \"cccc\");\n  db5_put(\"c\", \"c\");\n  db5_put(\"aaaaa\", \"aaaaa\");\n  db5_put(\"aa\", \"aa\");\n  db5_put(\"bb\", \"bb\");\n  db5_put(\"aaa\", \"aaa\");\n  db5_put(\"bbbbb\", \"bbbbb\");\n  db5_put(\"cc\", \"cc\");\n  db5_put(\"aaaaa\", \"aaaaa\");\n  db5_put(\"aaaa\", \"aaaa\");\n  db5_put(\"bbb\", \"bbb\");\n  db5_put(\"ccc\", \"ccc\");\n\n  fprintf(stdout,\"db5_set:%s\\n\", db5_set);\n  free(db5_set);\n  db5_set = NULL;\n\n  \/\/exit(1);\n\n#endif\n    \n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(!strcmp(\"-\",argv&#91;c])) { \/\/ filename - --&gt;stdin\n      strncpy(filename, argv&#91;c], sizeof(filename));\n      fp1 = stdin;\n\n    } else if(strncmp(\"-\", argv&#91;c], 1)) { \/\/ filename\n      strncpy(filename, argv&#91;c], sizeof(filename));\n\n    } else if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tverbose = 1;\n\n      } else if(!strcmp(\"--help\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--set\", argv&#91;c])) { \/\/ display db5_set\n\tset = !set;\n\n      } else if(!strcmp(\"--all\", argv&#91;c])) {\n\n\tall = !all;\n\n\tctrl = all;\n\tchars = all;\n\tcdiff = all;\n\twords = all;\n\twdiff = all;\n\t\n      } else if(!strcmp(\"--ctrl\", argv&#91;c])) {\n\tctrl = !ctrl;\n\n      } else if(!strcmp(\"--chars\", argv&#91;c])) {\n\tchars = !chars;\n\t\n      } else if(!strcmp(\"--cdiff\", argv&#91;c])) {\n\tcdiff = !cdiff;\n\n      } else if(!strcmp(\"--words\", argv&#91;c])) {\n\twords = !words;\n\n      } else if(!strcmp(\"--wdiff\", argv&#91;c])) {\n\twdiff = !wdiff;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\thelp = 1;\n\n      }\n    }\n  } \/\/ end of for(c = 1; c &lt; argc; c++)\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\", procname);\n    fprintf(stderr,\" &#91;-]\");\n    fprintf(stderr,\"\/&#91;filename]\");\n    fprintf(stderr,\" &#91;--verbose]\");\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--all]\");\n    fprintf(stderr,\" &#91;--ctrl]\");\n    fprintf(stderr,\" &#91;--chars]\");\n    fprintf(stderr,\" &#91;--cdiff]\");\n    fprintf(stderr,\" &#91;--words]\");\n    fprintf(stderr,\" &#91;--wdiff]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  \/\/ open needed random file\n  \n  if(!strcmp(filename, \"-\")) {\n    fp1 = stdin;\n  } else if((fp1 = fopen(filename, \"r\")) == NULL) {\n    fprintf(stderr,\"%s: fopen: cannot open file %s\", procname, filename);\n    exit(2);\n  }\n  \n#define MAXCOUNT 256\n\n  long int charcounts&#91;MAXCOUNT];\n  \n  for(c = 0; c &lt; MAXCOUNT; c++)\n    charcounts&#91;c] = 0;\n  \n#define MAX 1024\n  \n  unsigned long int singles = 0;\n\n  int ch;\n\n  first = 1;\n\n  unsigned char buffer&#91;1024];\n  unsigned char *ifile = NULL; \/\/ input file\n  unsigned long long ifilelength = 0;\n  \n  \/\/ read input file to buffer\n\n  while(fgets(buffer, sizeof(buffer), fp1) != NULL) {\n    if(verbose) {\n      fprintf(stdout,\"%s\", buffer);\n    }\n\n    int bytes = 0;\n\n    if(ifile != NULL)\n      bytes += strlen(ifile);\n    bytes += strlen(buffer);\n    bytes += 1;\n\n    if(ifilelength &lt; bytes) {\n      unsigned char *tempifile = ifile;\n      ifilelength = bytes;\n      if((ifile = realloc(ifile, ifilelength)) == NULL) {\n\tfprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n\texit(2);\n      }\n      if(tempifile == NULL)\n\tifile&#91;0] = '\\0';\n    }\n    strcat(ifile, buffer);\n  }\n\n  if(verbose)\n    fflush(stdout);\n  \n  unsigned char *p;\n  \n  p = ifile;\n\n  while((ch = *p++) != '\\0') {\n\n    \/\/ calculate character counts for\n    \/\/ character statistics\n    \n    charcounts&#91;ch]++;\n\n    if(ch &lt;= 0x20) { \/\/ ctrl or space, skip\n      continue;\n    }\n\n    singles++;\n\n  } \/\/ end of for(c = 0; c &lt; ifilelength; c++)\n\n  if(singles == 0) {\n    fprintf(stderr,\"%s: no data\\n\",procname);\n    exit(2);\n  }\n  \n  int wcount = 0; \/\/ word count\n  \n  p = ifile;\n\n  while(*p != '\\0') {\n\n    while(*p &lt;= 0x20 &amp;&amp; *p != '\\0') \/\/ skip control &amp;&amp; handle end of file\n      p++;\n\n    int count;\n    unsigned char *w, word&#91;128];\n\n    \/\/ get word\n    \n    w = word;\n    count = 0;\n    while(*p &gt; 0x20 &amp;&amp; *p != '\\0') {\n      if(++count &lt; sizeof(word))\n\t*w++ = *p;\n      p++;\n    }\n    *w = '\\0';\n\n    if(count &gt; 0) {\n      increment(word);\n      wcount++;\n    }\n  } \/\/ end of while(*p != '\\0')\n\n  if(set) {\n    fprintf(stdout,\"set       %s\\n\", db5_set);\n    fflush(stdout);\n  }\n  \n  unsigned long int count = 0, ctotal = 0;\n\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n    if(charcounts&#91;c] &gt; 0) {\n  \n      if(c &lt;= 0x20) \/\/ ctrl or space, skip\n\tcontinue;\n\n      ctotal += charcounts&#91;c];\n      count++;\n\n    } \/\/ if(charcounts&#91;c] &gt; 0)\n  } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n\n  \/\/ print control line if needed\n  \n  if(ctrl) {\n    char *ctrlchars&#91;] = {\n      \"NUL\", \"0x01\", \"0x02\", \"0x03\", \"0x04\", \"0x05\", \"0x06\", \"BEL\", \"BS\",\n      \"0x09\", \"LF\", \"0x0b\", \"0x0c\", \"CR\", \"0x0e\", \"0x0f\",\n      \"0x10\", \"0x11\", \"0x12\", \"0x13\", \"0x14\", \"0x15\", \"0x16\", \"0x17\", \"0x18\",\n      \"0x19\", \"0x1a\", \"ESC\", \"0x1c\", \"0x1d\", \"0x1e\", \"0x1f\",\n      \"space\"\n    };\n    \n    fprintf(stdout,\"ctrl      \");\n    first = 1;\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &gt; 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%s\", ctrlchars&#91;c]);\n\t\n\tfprintf(stdout,\":%lu\", charcounts&#91;c]);\n\t\n\tfirst = 0;\n      } \/\/ end of if(charcounts&#91;c] &gt; 0)\n    } \/\/ end of for(c = 0; c &lt; MAXCOUNT; c++)\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of if(ctrl)\n\n  unsigned long int caverage;\n\n  \/\/ calculate average for character statistics\n  \n  caverage = ctotal \/ count;\n\n  long int min;\n  long int max;\n  \n  \/\/ print character statistics\n\n  for(int e = 0; e &lt; 2; e++) {\n    long int total = 0;\n    min = LONG_MAX;\n    max = LONG_MIN;\n\n    if(e == 0) {\n      if(!chars)\n\tcontinue;\n      fprintf(stdout,\"chars     \");\n    } else {\n      if(!cdiff)\n\tcontinue;\n      fprintf(stdout,\"cdiff     \");\n    }\n    first = 1;\n\n    for(c = 0; c &lt; MAXCOUNT; c++) {\n      if(c &lt;= 0x20)\n\tcontinue;\n\n      if(charcounts&#91;c] &gt; 0) {\n\t\n\tif(!first)\n\t  fprintf(stdout, \", \");\n\t\n\tif(isprint(c) &amp;&amp; c &gt; ' ')\n\t  fprintf(stdout, \"%c\", c);\n\telse\n\t  fprintf(stdout,\"%02x\", c);\n\n\tlong int temp;\n\t\n\tif(e == 0)\n\t  temp = charcounts&#91;c];\n\telse\n\t  temp = caverage - charcounts&#91;c];\n\n\tfprintf(stdout,\":%ld\", temp);\n\n\ttotal += temp;\n\tif(min &gt; temp)\n\t  min = temp;\n\tif(max &lt; temp)\n\t  max = temp;\n\n\tfirst = 0;\n      }\n    } \/\/ end of if(charcounts&#91;c] &gt; 0)\n\n    if(e == 0) {\n      fprintf(stdout,\", words:%ld\", count);\n      fprintf(stdout,\", total:%ld\", total);\n      fprintf(stdout,\", average:%ld\", caverage);\n    } else {\n      fprintf(stdout,\", total:%ld\", total);\n    }\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/ end of for(int e = 0; e &lt; 2: e++)\n\n  unsigned char *iset = db5_get_set();\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  \n#define TEST80 2 \/\/ default on (for now)\n  \n#ifdef TEST80\n\n  for(c = 0; c &lt; MAXCOUNT; c++) {\n\n    if(c &lt;= 0x20)\n      continue;\n\n    long int tcount = 0;\n    \n    p = iset;\n\n    while(*p != '\\0') {\n      db5_skipwhite(&amp;p);\n      db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;p);\n      db5_skipwhite(&amp;p);\n      if(*p == ',') {\n\tp++;\n\tdb5_skipwhite(&amp;p);\n\tif(*p == ',') {\n\t  p++;\n\t  db5_skipwhite(&amp;p);\n\t  fprintf(stderr,\"%s: excess comma, set:%s\\n\", procname, iset);\n\t  fflush(stderr);\n\t  exit(1);\n\t}\n      }\n      long int temp;\n      unsigned char tempbuffer&#91;32];\n      \n      strncpy(tempbuffer, value, valuelen);\n      tempbuffer&#91;valuelen] = '\\0';\n      temp = atol(tempbuffer);\n\n      for(d = 0; d &lt; namelen; d++) {\n\tif(name&#91;d] == c)\n\t  tcount += temp;\n      }\n    } \/\/ end of while(*p != '\\0')\n\n#define aDEBUG84 2\n    \n#ifdef DEBUG84\n    if(charcounts&#91;c] != 0 || tcount != 0) {\n      fprintf(stderr,\"%s: test\", procname);\n      fprintf(stderr,\", c:%d\", c);\n      fprintf(stderr,\", charcount:%ld\", charcounts&#91;c]);\n      fprintf(stderr,\", tcount:%ld\\n\", tcount);\n    }\n#endif\n    if(charcounts&#91;c] != tcount) {\n      fprintf(stderr,\"%s: internal error:\", procname);\n      fprintf(stderr,\"wordcounts and charcounts do not match\");\n      fprintf(stderr,\", char:%c(0x%02x)\", c, c);\n      fprintf(stderr,\", charcount:%ld\", charcounts&#91;c]);\n      fprintf(stderr,\", tcount:%ld\", tcount);\n      fprintf(stderr,\"\\n\");\n      \/\/exit(2);\n    }\n  } \/\/ for(c = 0; c &lt; MAXCOUNT; c++)\t\n\n#endif\n  \n  unsigned long wtotal = 0;\n  unsigned long wordscnt = 0;\n  \n  \/\/ calculate words statistics average\n\n  \/\/ first words total and count\n  \n  p = iset;\n\n  \/\/ read thru elements element by element\n\n  while(*p != '\\0') {\n    db5_skipwhite(&amp;p);\n    db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;p);\n    db5_skipwhite(&amp;p);\n    if(*p == ',') {\n      p++;\n      db5_skipwhite(&amp;p);\n      if(*p == ',') {\n\tp++;\n\tdb5_skipwhite(&amp;p);\n\tfprintf(stderr,\"%s: excess comma, set:%s\\n\", procname, iset);\n\tfflush(stderr);\n\texit(1);\n      }\n    }\n\n    long int temp;\n    unsigned char tempbuffer&#91;32];\n\n    strncpy(tempbuffer, value, valuelen);\n    tempbuffer&#91;valuelen] = '\\0';\n    temp = atol(tempbuffer);\n    wtotal += temp;\n\n    wordscnt++;\n\n  } \/\/ end of while(*set != '\\0')\n\n  \/\/ average (words statistics)\n  \n  long int waverage = wtotal \/ wordscnt;\n\n  \/\/ print words statistics\n  \n  for(int e = 0; e &lt; 2; e++) {\n    unsigned long total = 0;\n    \n    min = LONG_MAX;\n    max = LONG_MIN;\n    \n    if(e == 0) {\n      if(!words)\n\tcontinue;\n      fprintf(stdout,\"words     \");\n    } else {\n      if(!wdiff)\n\tcontinue;\n      fprintf(stdout,\"wdiff     \");\n    }\n\n    unsigned char *iset = db5_get_set();\n    \n    \/\/ read thru elements element by element\n\n    first = 1;\n    p = iset;\n\n    while(*p != '\\0') {\n      if(!first)\n\tfprintf(stdout, \", \");\n      \n      db5_skipwhite(&amp;p);\n      db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;p);\n      db5_skipwhite(&amp;p);\n      if(*p == ',') {\n\tp++;\n\tdb5_skipwhite(&amp;p);\n\tif(*p == ',') {\n\t  p++;\n\t  db5_skipwhite(&amp;p);\n\t  fprintf(stderr,\"%s: excess comma, set:%s\\n\", procname, iset);\n\t  fflush(stderr);\n\t  exit(1);\n\t}\n      }\n\n      unsigned char tempbuffer&#91;32];\n      strncpy(tempbuffer, value, valuelen);\n      tempbuffer&#91;valuelen] = '\\0';\n      \n      long int temp;\n      if(e == 0)\n\ttemp = atol(tempbuffer);\n      else\n\ttemp = waverage - atol(tempbuffer);\n      \n      fprintf(stdout,\"%.*s:\", namelen, name);\n      fprintf(stdout,\"%ld\", temp);\n      \n      if(min &gt; temp)\n\tmin = temp;\n      if(max &lt; temp)\n\tmax = temp;\n      total += temp;\n\n      first = 0;\n    } \/\/ end of while(*set != '\\0')\n\n    if(e == 0) {\n      fprintf(stdout,\", words:%ld\", wordscnt);\n      fprintf(stdout,\", total:%ld\", total);\n      fprintf(stdout,\", average:%ld\", waverage);\n    } else {\n      fprintf(stdout,\", total:%ld\", total);\n    }\n\n    fprintf(stdout,\", min:%ld\", min);\n    fprintf(stdout,\", max:%ld\", max);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n  } \/\/end of for(e = 0;e &lt; 2; e++)\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 kuva DEBUG11:n tulostamasta listasta: Listalle tulee kaksi rivi\u00e4 (old ja new) silloin kun set:n koko muuttuu, eli k\u00e4yd\u00e4\u00e4n muuttamassa tietueen kokoa realloc:issa. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --dec --space --lineno -s1 -l10 | .\/newressutest9 --set | more\nold length:0 (null)\nnew length:10 '9' = \"1\"\nold length:10 '9' = \"1\"\nnew length:21 '0' = \"1\", '9' = \"1\"\nold length:21 '0' = \"1\", '9' = \"1\"\nnew length:32 '0' = \"1\", '7' = \"1\", '9' = \"1\"\nold length:32 '0' = \"1\", '7' = \"1\", '9' = \"1\"\nnew length:43 '0' = \"1\", '2' = \"1\", '7' = \"1\", '9' = \"1\"\nold length:43 '0' = \"1\", '2' = \"1\", '7' = \"1\", '9' = \"1\"\nnew length:54 '0' = \"1\", '2' = \"1\", '4' = \"1\", '7' = \"1\", '9' = \"1\"\nold length:54 '0' = \"1\", '2' = \"1\", '4' = \"1\", '7' = \"1\", '9' = \"1\"\nnew length:65 '0' = \"1\", '2' = \"1\", '3' = \"1\", '4' = \"1\", '7' = \"1\", '9' = \"1\"\nold length:65 '0' = \"1\", '2' = \"1\", '3' = \"1\", '4' = \"1\", '7' = \"1\", '9' = \"1\"\nnew length:76 '0' = \"1\", '2' = \"1\", '3' = \"1\", '4' = \"1\", '5' = \"1\", '7' = \"1\", '9' = \"1\"\nold length:76 '0' = \"2\", '2' = \"1\", '3' = \"1\", '4' = \"1\", '5' = \"1\", '7' = \"2\", '9' = \"1\"\nnew length:87 '0' = \"2\", '1' = \"1\", '2' = \"1\", '3' = \"1\", '4' = \"1\", '5' = \"1\", '7' = \"2\", '9' = \"1\"\nold length:87 '0' = \"5\", '1' = \"3\", '2' = \"1\", '3' = \"2\", '4' = \"1\", '5' = \"7\", '7' = \"3\", '9' = \"4\"\nnew length:98 '0' = \"5\", '1' = \"3\", '2' = \"1\", '3' = \"2\", '4' = \"1\", '5' = \"7\", '7' = \"3\", '8' = \"1\", '9' = \"4\"\nold length:98 '0' = \"5\", '1' = \"5\", '2' = \"1\", '3' = \"3\", '4' = \"5\", '5' = \"9\", '7' = \"3\", '8' = \"3\", '9' = \"5\"\nnew length:109 '0' = \"5\", '1' = \"5\", '2' = \"1\", '3' = \"3\", '4' = \"5\", '5' = \"9\", '6' = \"1\", '7' = \"3\", '8' = \"3\", '9' = \"5\"\nold length:109 '0' = \"5\", '1' = \"5\", '2' = \"1\", '3' = \"4\", '4' = \"5\", '5' = \"9\", '6' = \"1\", '7' = \"3\", '8' = \"3\", '9' = \"5\"\nnew length:110 '0' = \"5\", '1' = \"5\", '2' = \"1\", '3' = \"4\", '4' = \"5\", '5' = \"10\", '6' = \"1\", '7' = \"3\", '8' = \"3\", '9' = \"5\"\nold length:110 '0' = \"8\", '1' = \"9\", '2' = \"2\", '3' = \"5\", '4' = \"6\", '5' = \"14\", '6' = \"4\", '7' = \"4\", '8' = \"9\", '9' = \"6\"\nnew length:111 '0' = \"8\", '1' = \"9\", '2' = \"2\", '3' = \"5\", '4' = \"6\", '5' = \"14\", '6' = \"4\", '7' = \"4\", '8' = \"10\", '9' = \"6\"\nold length:111 '0' = \"8\", '1' = \"9\", '2' = \"2\", '3' = \"5\", '4' = \"6\", '5' = \"14\", '6' = \"4\", '7' = \"4\", '8' = \"10\", '9' = \"6\"\nnew length:112 '0' = \"8\", '1' = \"10\", '2' = \"2\", '3' = \"5\", '4' = \"6\", '5' = \"14\", '6' = \"4\", '7' = \"4\", '8' = \"10\", '9' = \"6\"\nold length:112 '0' = \"9\", '1' = \"15\", '2' = \"4\", '3' = \"6\", '4' = \"6\", '5' = \"15\", '6' = \"5\", '7' = \"5\", '8' = \"14\", '9' = \"6\"\nnew length:113 '0' = \"10\", '1' = \"15\", '2' = \"4\", '3' = \"6\", '4' = \"6\", '5' = \"15\", '6' = \"5\", '7' = \"5\", '8' = \"14\", '9' = \"6\"\nold length:113 '0' = \"11\", '1' = \"20\", '2' = \"6\", '3' = \"9\", '4' = \"8\", '5' = \"16\", '6' = \"6\", '7' = \"8\", '8' = \"17\", '9' = \"6\"\nnew length:114 '0' = \"11\", '1' = \"20\", '2' = \"6\", '3' = \"10\", '4' = \"8\", '5' = \"16\", '6' = \"6\", '7' = \"8\", '8' = \"17\", '9' = \"6\"\nold length:114 '0' = \"13\", '1' = \"20\", '2' = \"6\", '3' = \"10\", '4' = \"9\", '5' = \"17\", '6' = \"8\", '7' = \"8\", '8' = \"18\", '9' = \"7\"\nnew length:115 '0' = \"13\", '1' = \"20\", '2' = \"6\", '3' = \"10\", '4' = \"10\", '5' = \"17\", '6' = \"8\", '7' = \"8\", '8' = \"18\", '9' = \"7\"\nold length:115 '0' = \"13\", '1' = \"20\", '2' = \"7\", '3' = \"11\", '4' = \"11\", '5' = \"21\", '6' = \"8\", '7' = \"9\", '8' = \"19\", '9' = \"8\"\nnew length:116 '0' = \"13\", '1' = \"20\", '2' = \"7\", '3' = \"11\", '4' = \"11\", '5' = \"21\", '6' = \"8\", '7' = \"10\", '8' = \"19\", '9' = \"8\"\nold length:116 '0' = \"15\", '1' = \"22\", '2' = \"7\", '3' = \"11\", '4' = \"12\", '5' = \"21\", '6' = \"9\", '7' = \"10\", '8' = \"19\", '9' = \"9\"\nnew length:117 '0' = \"15\", '1' = \"22\", '2' = \"7\", '3' = \"11\", '4' = \"12\", '5' = \"21\", '6' = \"9\", '7' = \"10\", '8' = \"19\", '9' = \"10\"\nold length:117 '0' = \"15\", '1' = \"22\", '2' = \"8\", '3' = \"11\", '4' = \"12\", '5' = \"22\", '6' = \"9\", '7' = \"10\", '8' = \"20\", '9' = \"10\"\nnew length:118 '0' = \"15\", '1' = \"22\", '2' = \"8\", '3' = \"11\", '4' = \"12\", '5' = \"22\", '6' = \"10\", '7' = \"10\", '8' = \"20\", '9' = \"10\"\nold length:118 '0' = \"20\", '1' = \"25\", '2' = \"9\", '3' = \"14\", '4' = \"14\", '5' = \"25\", '6' = \"14\", '7' = \"15\", '8' = \"23\", '9' = \"11\"\nnew length:119 '0' = \"20\", '1' = \"25\", '2' = \"10\", '3' = \"14\", '4' = \"14\", '5' = \"25\", '6' = \"14\", '7' = \"15\", '8' = \"23\", '9' = \"11\"\nset       '0' = \"36\", '1' = \"43\", '2' = \"26\", '3' = \"28\", '4' = \"35\", '5' = \"44\", '6' = \"31\", '7' = \"40\", '8' = \"47\", '9' = \"30\"\nctrl      LF:10, space:350\nchars     0:36, 1:43, 2:26, 3:28, 4:35, 5:44, 6:31, 7:40, 8:47, 9:30, words:10, total:360, average:36, min:26, max:47\ncdiff     0:0, 1:-7, 2:10, 3:8, 4:1, 5:-8, 6:5, 7:-4, 8:-11, 9:6, total:0, min:-11, max:10\nwords     0:36, 1:43, 2:26, 3:28, 4:35, 5:44, 6:31, 7:40, 8:47, 9:30, words:10, total:360, average:36, min:26, max:47\nwdiff     0:0, 1:-7, 2:10, 3:8, 4:1, 5:-8, 6:5, 7:-4, 8:-11, 9:6, total:0, min:-11, max:10\n$ <\/code><\/pre>\n\n\n\n<p>Uudelleenkirjoitin my\u00f6s newressun stat_line rutiinit: uudessa versiossa ideana on ett\u00e4 tilarivi tulostetaan vain, jos se on muuttunut. Uudessa versiossa tilarivi kootaan stat_line muuttujaan ja end() rutiinissa koko rivi tulostetaan, jos se on muuttunut. End() rutiini tallettaa stat_line muuttujan prev_stat_line muuttujaan seuraavaa vertailua varten. cursor_remove() ja cursor_start() kutsut on siirretty _end() rutiiniin. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int cursor_on = 0;\nunsigned char cursor&#91;4] = { '|', '\/', '-', '\\\\' };\nlong int prev_secs = -1;\nint crs = 0;\n\nvoid stat_line_cursor_start()\n{\n  fprintf(stderr, \" \");\n  fflush(stderr);\n  prev_secs = -1;\n  cursor_on = 1;\n}\n\nvoid stat_line_cursor()\n{\n  long int secs;\n\n  secs = time(NULL) % sizeof(cursor);\n  if(prev_secs != secs) {\n    if(prev_secs != -1) \n      crs = (crs + 1) % sizeof(cursor);\n    fprintf(stderr,\"\\b%c\", cursor&#91;crs]);\n    fflush(stderr);\n    prev_secs = secs;\n  }\n}\n\nvoid stat_line_cursor_remove()\n{\n  if(cursor_on) {\n    fprintf(stderr, \"\\b \\b\");\n    fflush(stderr);\n    prev_secs = -1;\n  }\n  cursor_on = 0;\n}\n\n#include &lt;stdarg.h&gt;\n\n#define aDEBUG31 2\n\nunsigned char *procname = NULL;\n\nstatic unsigned char *prev_stat_line = NULL;\nstatic unsigned char *stat_line = NULL;\nstatic size_t stat_line_length = 0;\n\nstatic void stat_line_begin()\n{\n  if(stat_line != NULL)\n    stat_line&#91;0] = '\\0';\n}\n\nstatic void stat_line_printf(const unsigned char *format, ...)\n{\n  int count;\n  va_list args;\n  static unsigned char *buffer = NULL;\n  static size_t buffer_length = 0;\n\n  va_start(args, format);\n  count = vsnprintf(buffer, buffer_length, format, args) + 1;\n  va_end(args);\n\n  if(buffer_length &lt; count) {\n    buffer_length = count;\n    buffer = realloc(buffer, buffer_length);\n    va_start(args, format);\n    count = vsnprintf(buffer, buffer_length, format, args) + 1;\n    va_end(args);\n  }\n\n  count = 0;\n  if(stat_line != NULL)\n    count += strlen(stat_line);\n  count += strlen(buffer);\n  count++;\n  \n  if(stat_line_length &lt; count) {\n    unsigned char *stat_line2 = stat_line;\n    stat_line_length = count;\n    stat_line = realloc(stat_line, stat_line_length);\n    prev_stat_line = realloc(prev_stat_line, stat_line_length);\n    if(stat_line2 == NULL) {\n      stat_line&#91;0] = '\\0';\n      prev_stat_line&#91;0] = '\\0';\n    }\n  }\n  strcat(stat_line, buffer);\n}\n\n#define READABLE_NUMBER_BIN 2\n\n#ifdef READABLE_NUMBER_BIN\n#define READABLE_NUMBER_HIGH 1023\n#define READABLE_NUMBER_DIVIDER 1024\n#else\n#define READABLE_NUMBER_HIGH 999\n#define READABLE_NUMBER_DIVIDER 1000\n#endif\n\n#define READABLE_NUMBER_WIDTH 32\n\nstatic void stat_line_get_readable(unsigned char buf10&#91;10], unsigned long length)\n{\n  int c, low;\n  double length2;\n\n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  strcpy(buf10, \"***\");\n  low = 0;\n\n  for(c = 0; length &gt;= low &amp;&amp;\n      c &lt; sizeof(units) - 1; c++) {\n    if(length &gt;= low &amp;&amp;\n       length &lt;= READABLE_NUMBER_HIGH) {\n      if(units&#91;c] == 'B')\n        sprintf(buf10, \"%ld\", length);\n      else if(units&#91;c] == 'K' ||\n\t      units&#91;c] == 'M' ||\n\t      units&#91;c] == 'G' ||\n\t      units&#91;c] == 'T')\n\tsprintf(buf10, \"%.3f\", length2);\n      else if(length == length2)\n\tsprintf(buf10, \"%ld\", length);\n      else\n\tsprintf(buf10, \"%.1f\", length2);\n\n      if(strchr(buf10, '.') != NULL) {\n\tint d;\n\td = strlen(buf10) - 1;\n\twhile(d &gt; 3 &amp;&amp; isdigit(buf10&#91;d])) {\n\t  buf10&#91;d] = '\\0';\n\t  d--;\n\t}\n\tif(buf10&#91;strlen(buf10)-1] == '.')\n\t  buf10&#91;strlen(buf10)-1] ='\\0';\n      }\n\n      if(units&#91;c] != 'B') {\n\tchar unit&#91;10];\n\tsprintf(unit,\"%cB\",units&#91;c]);\n\tstrcat(buf10, unit);\n      }\n      break;\n    }\n    length2 = (double)length \/ READABLE_NUMBER_DIVIDER;\n    length \/= READABLE_NUMBER_DIVIDER;\n    low = 1;\n  }\n}\n\nstatic void stat_line_readable(unsigned long length)\n{\n  unsigned char buf10&#91;10];\n  stat_line_get_readable(buf10, length);\n  stat_line_printf(\"%s\", buf10);\n}\n\nvoid stat_line_end()\n{\n  int c, d;\n\n  if(stat_line != NULL &amp;&amp; strcmp(prev_stat_line, stat_line)) { \/\/ status line changed\n    stat_line_cursor_remove();\n#ifdef DEBUG31\n    fprintf(stderr, \"\\n\");\n#else\n    fprintf(stderr, \"\\r\");\n#endif  \n\n    fprintf(stderr,\"%s\", stat_line);\n    fflush(stderr);\n\n    \/\/ previous line longer than this one,\n    \/\/ overwrite with spaces and backspace to\n    \/\/ end\n    \n    d = strlen(prev_stat_line) - strlen(stat_line) + 1; \/\/ cursor too\n\n    if(d &gt; 0) { \/\/ previous line longer\n      for(c = 0; c &lt; d; c++) {\n#ifdef DEBUG31\n\tfprintf(stderr, \"*\");\n#else\n\tfprintf(stderr, \" \"); \/\/ print spaces\n#endif\n      }\n#ifndef DEBUG31\n      for(c = 0; c &lt; d; c++)\n\tfprintf(stderr, \"\\b\"); \/\/ and backspaces\n#endif\n    }\n    strcpy(prev_stat_line, stat_line);\n    if(strlen(stat_line) &gt; 0)\n      stat_line_cursor_start();\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>sample() rutiini eli tiedoston muodostaminen satunnaisbiteist\u00e4 sai my\u00f6s uudelleenkirjoitusta. Aiemmin koodissa oli kaikkia clim ja dlim muuttujia, uudessa versiossa on vain tiedoston pituus merkkein\u00e4 ja blokin koko. Lis\u00e4ksi aiemmat cursor_remove ja cursor_start rutiinit on poistettu niiden stat_line rutiiniin lis\u00e4\u00e4misen takia. Tiedoston nimeen on lis\u00e4tty sarjanumero, joten sample ei poista aiempia tuloksia. Pilkkujen k\u00e4ytt\u00f6\u00e4 tilariviss\u00e4 on muutettu. Dieharder-satunnaislukuanalyysin voi my\u00f6s ajaa automaattisesti sample ajon j\u00e4lkeen. (&#8211;dieharder komentorivitoiminto). Die tulee ilmeisesti sanasta noppa.. Sample rutiinissa on ajon aikainen tilarivi, siin\u00e4 on esimerkki aiempien rutiinien k\u00e4yt\u00f6st\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int sample = 0, dieharder = 0; \/\/ randomness analysis\n\n\/\/ try randomness analysis with: $ dieharder -a -g 201 -f newressusample1.rnd &gt; newressusample1.rnd.dieharder\n\n#include &lt;signal.h&gt;\n\ntypedef void (*sighandler_t)(int);\n\nvoid sample_handler()\n{\n  static int times = 0;\n\n  times++;\n\n  fprintf(stderr,\"Ctrl-c pressed %d times\\n\", times);\n  if(times &gt;= 10) {\n    signal(SIGINT, SIG_DFL);\n    exit(1);\n  }\n}\n\n#define DEBUG39\n\n#define FILESIZE 1 * 1024 * 1024 * 1024\n#define BLOCKSIZE 128 * 1024\n#define BLOCKS 8 * 1024\n\nunsigned long long filesize = FILESIZE, blocks = BLOCKS;\nunsigned int blocksize = BLOCKSIZE;\nint filesize_set = 0, blocks_set = 0, blocksize_set = 0;\n\nvoid dump_sample() \/\/ &amp; dieharder analysis\n{\n#define STAT_LINE_SHOW_BLOCK 2 \/\/ on by default\n#define STAT_LINE_SHOW_WRITTEN 2 \/\/ on by default\n#define STAT_LINE_SHOW_SPEED 2 \/\/ on by default\n#define STAT_LINE_SHOW_NOW 2 \/\/ on by default\n#define STAT_LINE_SHOW_LEFT 2 \/\/ on by default\n#define STAT_LINE_SHOW_READY 2 \/\/ on by default\n\n#define STAT_LINE_LESS_WOBBLE 2 \/\/ on by default\n\n#define TIMEFORMAT \"%H:%M %Z\"\n#define TIMEFORMAT2 \"%a %H:%M %Z\"\n#define DATEFORMAT \"%a %d %b %Y\"\n    \n  unsigned long long c;\n  unsigned char *buffer, filename&#91;128], command&#91;1024];\n  \n  FILE *fp1;\n  \n  \/\/ find first available filename,\n  \/\/ or empty \"fileslot\"\n  \n  for(c = 1; c &lt;= 99999; c++) {\n    sprintf(filename, samplefilename, c);\n    if((fp1 = fopen(filename, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n    unsigned char filename2&#91;138];\n    sprintf(filename2,\"%s.dieharder\",filename);\n    if((fp1 = fopen(filename2, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n#ifdef SAMPLE_HASH\n    sprintf(filename2,\"%s.sha256\",filename);\n    if((fp1 = fopen(filename2, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n#endif\n    break;\n  }\n\n  \/\/ calculate missing file size parameters\n  \n  if(!filesize_set)\n    filesize = blocks * blocksize;\n  else if(!blocksize_set) {\n    blocksize = (filesize + blocks - 1) \/ blocks; \/\/ round up\n    filesize = blocks * blocksize;\n  } else if(!blocks_set) {\n    blocks = (filesize + blocksize - 1)\/ blocksize; \/\/ round up\n    filesize = blocks * blocksize;\n  }\n\n#define aEXFAT_FIX 2 \/\/ on for now\n  \n#ifdef EXFAT_FIX\n\n  if(blocksize &gt; KILO * KILO) { \/\/ max \"blocksize\" 1m (exfat)\n    blocksize = KILO * KILO;\n    blocks = (filesize + blocksize - 1) \/ blocksize;\n    filesize = blocks * blocksize;\n  }\n\n#endif\n  \n  if(filesize != blocks * blocksize ||\n     blocks &lt; 1 || blocksize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): mismatched parameters\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n  \n  if(filesize \/ blocks != blocksize) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): parameter overflow\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n#ifdef DEBUG39\n  fprintf(stderr,\"blocksize:%u(\", blocksize);\n  readablelonglong(stderr, blocksize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", blocks:%llu(\", blocks);\n  readablelonglong(stderr, blocks);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\\n\");\n  fflush(stderr);\n#endif\n\n  if((buffer = malloc(blocksize)) == NULL) {\n    fprintf(stderr,\"%s: sample(): cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n  }\n  \n#define DEBUG40 2 \/\/ default on (for now)\n    \n#ifdef DEBUG40\n  fprintf(stderr,\"%s: sample(): writing file\", procname);\n  fprintf(stderr,\", filename:%s\", filename);\n#ifndef SAMPLE_WRITE\n  fprintf(stderr,\", no write\");\n#endif\n  fprintf(stderr,\"\\n\");\n#endif\n  \n#ifdef SAMPLE_HASH\n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n  \n  HashInit(&amp;hash); \/\/ calculate hash\n#endif\n\n  \/\/ variables for stat line fields\n\n  time_t start, now, left, end;\n  unsigned char speed&#91;10], printspeed&#91;10] = \"\";\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n  time_t prevend = -1;\n  int countspeed = 0, countend = 0;\n  unsigned char prevspeed&#91;10] = \"\";\n  unsigned int calculateleft;\n\n#endif\n\n  time_t printleft = -1, printend = -1;\n  int leftprinted = 0;\n  \n  if((fp1 = fopen(filename, \"a\")) != NULL) {\n\n    \/\/ starting time\n    \n    start = time(NULL);\n    \n    unsigned long long clim = (unsigned long long) filesize \/ blocksize;\n\n#ifdef EXFAT_FIX\n    int mbinblocks = (1 * KILO * KILO) \/ blocksize;\n    if(mbinblocks == 0)\n      mbinblocks = 1;\n    fprintf(stderr,\"mbinblocks:%d\\n\", mbinblocks);\n#endif\n    \n    \/\/ you have to press ctrl-c 10 times\n\n    signal(SIGINT, sample_handler);\n    \n    for(c = 0; c &lt; clim; c++) {\n\n      \/\/ current time\n      \n      now = time(NULL);\n\n      \/\/ estimate for ending time\n      \n      end = (time_t)start + ((((double)now - start) \/ c) * clim);\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n      calculateleft = 0; \n      if(prevend \/ 60 == end \/ 60 &amp;&amp;\n\t ++countend &gt;= 30) { \/\/ 30 times same minutes --&gt; minutes are real\n\n\tprintend = end;\n\tcalculateleft = 1;\n      } else if(prevend \/ 60 != end \/ 60) { \/\/ minutes different\n\tprevend = end;\n\tcountend = 0;\n      }\n\n#else\n      printend = end;\n#endif\n\n      \/\/ estimate for time left\n\n      left = printend - now;\n\n#ifdef STAT_LINE_LESS_WOBBLE\n      \n      static int onlyseconds = 0;\n      static long long cstart, cleft;\n      \n      if(onlyseconds || (left &gt; 0 &amp;&amp; left &lt; 60)) {\n\tif(!onlyseconds) {\n\t  cstart = c;\n\t  cleft = clim - c;\n\t  onlyseconds = 1;\n\t}\n\n\tleft = (time_t) 60 - ((((double) c - cstart) \/ cleft) * 60);\n      }\n\n      if(calculateleft)\n\tprintleft = left;\n      \n#else\n      printleft = left;\n#endif\n\n      \/\/ speed\n      \n      if(now - start &gt; 1.0)\n\tstat_line_get_readable(speed, (unsigned long long)((double)c * blocksize \/ (now - start)) );\n      else\n\tstat_line_get_readable(speed, (unsigned long long)((double)c * blocksize));\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n      if(!strcmp(prevspeed, speed) &amp;&amp;\n\t ++countspeed &gt;= 3) { \/\/ three times same speed --&gt; speed is real\n\tstrcpy(printspeed, speed);\n      } else if(strcmp(prevspeed, speed)) {\n\tstrcpy(prevspeed, speed);\n\tcountspeed = 0;\n      }\n\n#else\n      strcpy(printspeed, speed);\n#endif\n      \n      \/\/ print status line:\n      \/\/ blk 10, written 10MB, 269KB\/sec, left 8 h 38 m, ready at Sat 17 Jul 2021 01:57:43 EEST, now Fri 17:19:32 EEST\n      \n      stat_line_begin();\n      \n      int print = 0;\n#ifdef STAT_LINE_SHOW_BLOCK\n      \n      stat_line_printf(\"%s\", randomgen&#91;input]);\n      \n      \/\/ print block from 0 to 8192\n      \n      stat_line_printf(\"block %d\", c);\n      print = 1;\n#endif\n      \n#ifdef STAT_LINE_SHOW_WRITTEN\n      \n      \/\/ print written\n      \n      if(print)\n\tstat_line_printf(\", \");\n      \n      stat_line_printf(\"written \");\n      stat_line_readable((unsigned long)c * blocksize);\n      print = 1;\n#endif\t  \n      if(c &gt; 0) {\n\t\n#ifdef STAT_LINE_SHOW_SPEED\n\t\n\t\/\/ print speed\n\t\n\tif(printspeed&#91;0] != '\\0') {\n\t  if(print)\n\t    stat_line_printf(\", \");\n\n\t  stat_line_printf(\"%s\/sec\", printspeed);\n\t  print = 1;\n\t}\n#endif\n\t\n#if defined STAT_LINE_SHOW_NOW ||\t\t\t\\\n  defined STAT_LINE_SHOW_READY\n\tchar timebuf&#91;128];\n#endif\n\t\n#ifdef STAT_LINE_SHOW_READY\n\tchar timebuf2&#91;128];\n#endif\n\t\n#ifdef STAT_LINE_SHOW_NOW\n\t\n\t\/\/ print now\n\t\n\tif(print)\n\t  stat_line_printf(\", \");\n\t\n\tstat_line_printf(\"now\");\n\tstrftime(timebuf, sizeof(timebuf), TIMEFORMAT2,\n\t\t localtime((time_t *)&amp;now));\n\tstat_line_printf(\" %s\", timebuf);\n\tprint = 1;\n#endif\n\t\n#ifdef STAT_LINE_SHOW_LEFT\n\t\n\t\/\/ print left\n\t\n\tif(printleft &gt; 0) {\n\n\t  unsigned long int left2;\n\t  unsigned long int temp;\n\t  int timeprinted = 0;\n\t  \n\t  if(print)\n\t    stat_line_printf(\", \");\n\n\t  left2 = printleft;\n\t  stat_line_printf(\"left\");\n\t  \n\t  temp = left2 \/ (24 * 3600); \/\/ days\n\t  if(temp &gt; 0) {\n\t    timeprinted = 1;\n\t    stat_line_printf(\" %dd\", temp);\n\t    left2 -= temp * (24 * 3600);\n\t  }\n\t  \n\t  temp = left2 \/ 3600; \/\/ hours\n\t  if(temp &gt; 0 || timeprinted) {\n\t    timeprinted = 1;\n\t    \/\/hoursprinted = 1;\n\t    stat_line_printf(\" %02dh\", temp);\n\t    left2 -= temp * 3600;\n\t  }\n\t  \n\t  temp = left2 \/ 60; \/\/ minutes\n\t  if(temp &gt; 0 || timeprinted) {\n\t    timeprinted = 1;\n\t    stat_line_printf(\" %02dm\", temp);\n\t    left2 -= temp * 60;\n\t  }\n\t  \n\t  temp = left2; \/\/ seconds\n\t  if(!timeprinted) {\n\t    stat_line_printf(\" %d seconds\", temp);\n\t  }\n\n\t  leftprinted = 1;\n\t  print = 1;\n\t}\n#endif\n\t\n#ifdef STAT_LINE_SHOW_READY\n\t\n\t\/\/unsigned long int end = (int)start + ((((double)now - start) \/ c) * clim);\n\n\tif(printend &gt; 0 &amp;&amp; leftprinted) {\n\t  if(print)\n\t    stat_line_printf(\", \");\n\t  \n\t  stat_line_printf(\"ready at\");\n\t  strftime(timebuf, sizeof(timebuf), DATEFORMAT,\n\t\t   localtime((time_t *) &amp; end));\n\t  strftime(timebuf2, sizeof(timebuf2), DATEFORMAT,\n\t\t   localtime((time_t *) &amp; now));\n\t  if(strcmp(timebuf, timebuf2)) {\n\t    stat_line_printf(\" %s\", timebuf);\n\t  }\n\t  \n\t  \/\/ print end time\n\t  \n\t  strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t\t   localtime((time_t *) &amp; printend));\n\t  stat_line_printf(\" %s\", timebuf);\n\t  \n\t  print = 1;\n\t}\n#endif\n      }\n      stat_line_end();\n      stat_line_cursor_start();\n      \n      \/\/ do the work\n      \n      stat_line_cursor();\n      \n      memset(buffer, 0, blocksize);\n      \n      if(input == INPUT_RESSU) \/\/ ressu prod\n\tressu_genbytes(blocksize, buffer);\n      \n      else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n\tpseudoressu_bytes(blocksize, buffer);\n      \n      else if(input == INPUT_FASTRESSU) \/\/ ressu fast\n\tressu_genbytes_fast(blocksize, buffer);\n      \n      else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n\tressu_genbytes_single(blocksize, buffer);\n      \n      else if(input == INPUT_STREAM) \/\/ ressu stream\n\tstream_bytes(blocksize, buffer);\n      \n#ifdef FORT\n      else if(input == INPUT_FORT) \/\/ ressu fort\n\tfort_random_data(blocksize, buffer);\n      \n      else if(input == INPUT_FORTXOR) \/\/ ressu fort\n\tfort_random_data_xor(blocksize, buffer);\n      \n#endif\n#ifdef USE_RDRAND\n      else if(input == INPUT_RDRAND) \/\/ intel rdrand\n\trdrand_bytes(blocksize, buffer);\n      \n#endif\n#ifdef USE_RDSEED\n      else if(input == INPUT_RDSEED) \/\/ intel rdseed\n\trdseed_bytes(blocksize, buffer);\n      \n#endif\n      else if(input == INPUT_URANDOM) \/\/ urandom\n\treadfile_xor(blocksize, buffer, urandomfilename);\n      \n#ifdef USE_RANDOM\n      else if(input == INPUT_RANDOM) \/\/ random\n\treadfile_xor(blocksize, buffer, randomfilename);\n      \n#endif\n#ifdef USE_DUMMY\n      else if(input == INPUT_DUMMY) {\n\t\/\/ no generator\n      }\n#endif\n      else {\n\tfprintf(stdout,\"\\n%s: mode '%d'(%s) not available\\n\",\n\t\tprocname, input, randomgen&#91;input]);\n\texit(2);\n      }\n#ifdef SAMPLE_HASH\n      HashUpdate(&amp;hash, buffer, blocksize); \/\/ calculate hash\n#endif\n#ifdef SAMPLE_WRITE\n      if(input != INPUT_DUMMY) {\n\tfwrite(buffer, 1, blocksize, fp1);\n\t\n#ifdef SAMPLE_SYNC\n\n#ifdef EXFAT_FIX\n\tif(c % mbinblocks == 0) { \/\/ fflush and sync (EXFAT)\n\t  fflush(fp1);\n\t  sync();\n\t  \/\/fprintf(stderr,\"*\\n\");\n\t}\n#endif\n\n#endif\n      } \/\/ end of if(input != INPUT_DUMMY\n#endif\n    } \/\/ end of for(c = 0; c &lt; clim; c++\n#ifdef SAMPLE_HASH\n    HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n\n    fflush(fp1); \/\/ fflush and sync (EXFAT)\n    sync();\n    \n    fclose(fp1);\n    \n  } else { \/\/ if((fp1=fopen\n    fprintf(stderr,\"%s:\", procname);\n    fprintf(stderr,\" sample(): cannot open file\");\n    fprintf(stderr,\", filename: %s\", filename);\n    fprintf(stderr,\"\\n\");\n    exit(2);\n  }\n  \n  \/\/ remove last status line\n\n  stat_line_cursor_remove();\n  \n  stat_line_begin();\n  \n  stat_line_printf(\"\\rwrote \");\n  stat_line_readable((unsigned long)c * blocksize);\n  \n  stat_line_printf(\", \");\n  if(now - start &gt;= 1.0)\n    stat_line_readable((unsigned long)((double)c * blocksize \/ (now - start)) );\n  else\n    stat_line_readable((unsigned long)c * blocksize);\n  stat_line_printf(\"\/sec\");\n  \n  stat_line_printf(\", done!\");\n  stat_line_end();\n  stat_line_cursor_remove();\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n\n#ifdef SAMPLE_HASH\n  unsigned char filename2&#91;138];\n  unsigned char hashstring&#91;2 * HashLen + 1];\n  \n  hashfinal2string(hashstring, digest);\n\n  sprintf(filename2,\"%s.sha256\", filename);\n  \n  fprintf(stderr,\"%s: sample(): hashing file\", procname);\n  fprintf(stderr,\", filename:%s\", filename);\n  fprintf(stderr,\", hashfilename:%s\", filename2);\n  fprintf(stderr,\", sha256:%s\\n\", hashstring);\n  \n  if((fp1 = fopen(filename2, \"a\")) != NULL) {\n    fprintf(fp1,\"%s\\n\",hashstring);\n    fclose(fp1);\n  }\n  fprintf(stderr,\"%s: sample(): checking sha256\", procname);\n  fprintf(stderr,\", filename:%s\\n\", filename);\n  sprintf(command,\"sha256sum %s\", filename);\n  system(command);\n#endif\n\n  signal(SIGINT, SIG_DFL);\n\n  free(buffer);\n  \n  if(dieharder) { \/\/ randomness analysis\n    \n    sprintf(command,\"dieharder -a -g 201 -f %s &gt; %s.dieharder 2&gt;&amp;1\", filename, filename);\n    \/\/sprintf(command,\"dieharder -a -g 201 -f %s &gt; %s.dieharder\", filename, filename);\n    fprintf(stderr,\"%s: sample(): running dieharder \\\"%s\\\"\\n\", procname, command);\n    system(command);\n    sprintf(command,\"grep \\\"WEAK\\\\|FAILED\\\" %s.dieharder\", filename);\n    fprintf(stderr,\"%s: sample(): grepping diehard problems \\\"%s\\\"\\n\", procname, command);\n    system(command);\n    sprintf(command,\"grep rewound %s.dieharder | tail -n1\", filename);\n    fprintf(stderr,\"%s: sample(): grepping last rewound count \\\"%s\\\"\\n\", procname, command);\n    system(command);\n    exit(0);\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavassa ajetaan sample() ja &#8211;dieharder analyysi: Dieharder on antanut yleens\u00e4 muutamia WEAK:keja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single --sample --dieharder\n.\/newressu: sample: writing file, filename:newressusample1.rnd\nwrote 16.0GB, 4.1MB\/sec, done!                                                                           \n.\/newressu: dieharder: running dieharder \"dieharder -a -g 201 -f newressusample1.rnd &gt; newressusample1.rnd.dieharder\"\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 4 times\n# The file file_input_raw was rewound 4 times\n# The file file_input_raw was rewound 5 times\n# The file file_input_raw was rewound 5 times\n# The file file_input_raw was rewound 6 times\n# The file file_input_raw was rewound 6 times\n# The file file_input_raw was rewound 7 times\n# The file file_input_raw was rewound 7 times\n# The file file_input_raw was rewound 8 times\n# The file file_input_raw was rewound 8 times\n# The file file_input_raw was rewound 9 times\n# The file file_input_raw was rewound 9 times\n# The file file_input_raw was rewound 10 times\n# The file file_input_raw was rewound 11 times\n# The file file_input_raw was rewound 12 times\n# The file file_input_raw was rewound 12 times\n# The file file_input_raw was rewound 13 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n\n$ fgrep WEAK newressusample1.rnd.dieharder \n      rgb_lagged_sum|  18|   1000000|     100|0.99605238|   WEAK   \nmedia$ fgrep FAILED newressusample1.rnd.dieharder \nmedia$<\/code><\/pre>\n\n\n\n<p>Edellisess\u00e4 ajossakin tuli pari heikosti suoriuduttua rivi\u00e4.<\/p>\n\n\n\n<p>Poistettu .\/newressu &#8211;sample &#8211;dieharder ohjelmasta nuo aiemman esimerkin &#8220;The file&#8221; rivit ja listattu grepill\u00e4 loppuun &#8211;dieharder:in ongelmat:<\/p>\n\n\n\n<p>Bugiv\u00e4like: T\u00e4st\u00e4 raportista tuli varsinainen bugiraportti, ensin ressussa l\u00f6ytyi tuo +2 ongelma, sitten ongelmia usb levyn kanssa (talletettu tiedosto ei ollut fixed length). N\u00e4ist\u00e4 +2 bugi sai korjauksen, joten j\u00e4ljelle j\u00e4i usb ongelma. Kokeilin ajaa &#8211;sample &#8211;dieharderin usb levyll\u00e4, ja se meni l\u00e4pi ihan ok: t\u00e4ll\u00e4 kertaa yksi WEAK:ki. Huomaa my\u00f6s ett\u00e4 ajo on tehty &#8211;single moodilla..<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>media$ .\/newressu --single --sample --dieharder\n.\/newressu: sample: writing file, filename:newressusample1.rnd\nwrote 16.0GB, 4.1MB\/sec, done!                                                                           \n.\/newressu: dieharder: running dieharder \"dieharder -a -g 201 -f newressusample1.rnd &gt; newressusample1.rnd.dieharder\"\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 1 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 2 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 3 times\n# The file file_input_raw was rewound 4 times\n# The file file_input_raw was rewound 4 times\n# The file file_input_raw was rewound 5 times\n# The file file_input_raw was rewound 5 times\n# The file file_input_raw was rewound 6 times\n# The file file_input_raw was rewound 6 times\n# The file file_input_raw was rewound 7 times\n# The file file_input_raw was rewound 7 times\n# The file file_input_raw was rewound 8 times\n# The file file_input_raw was rewound 8 times\n# The file file_input_raw was rewound 9 times\n# The file file_input_raw was rewound 9 times\n# The file file_input_raw was rewound 10 times\n# The file file_input_raw was rewound 11 times\n# The file file_input_raw was rewound 12 times\n# The file file_input_raw was rewound 12 times\n# The file file_input_raw was rewound 13 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n# The file file_input_raw was rewound 14 times\n\nmedia$ fgrep WEAK newressusample1.rnd.dieharder \n      rgb_lagged_sum|  18|   1000000|     100|0.99605238|   WEAK   \nmedia$ fgrep FAILED newressusample1.rnd.dieharder \nmedia$<\/code><\/pre>\n\n\n\n<p>.rnd tiedostossa oli my\u00f6s oikea koko. Itse k\u00e4yt\u00e4n usb levyj\u00e4 koko ajan ja ajattelinkin ihmetell\u00e4 sit\u00e4 viel\u00e4 hetken.. Sample():n tulos on tietysti jatkuva tiedosto, joten muutoksia siin\u00e4 ei n\u00e4e. Lis\u00e4tty\u00e4 tietoa ei ilmeisesti (koon perusteella) ole.<\/p>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 tuloste uusimmasta &#8211;sample versiosta, joka ei tulosta aiempia &#8220;The file&#8221; -rivej\u00e4 vaan vain FAIL ja WEAK rivit ja useammista tiedoston l\u00e4pik\u00e4ynneist\u00e4. Seuraavassa listauksessa materiaali on k\u00e4yty l\u00e4pi 229m kertaa ja l\u00f6ytyi 1 WEAK:ki. Ainakin osa weakeista aiheutuu mielest\u00e4ni liian pienest\u00e4 materiaalista. Huomaa my\u00f6s ett\u00e4 t\u00e4ss\u00e4 on k\u00e4ytetty &#8211;single toimintoa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --single --sample --dieharder --filesize1g\nstring:'1g', base:10(10B), multiplier:1073741824(1G), prevll:1(1B), ll:1073741824(1G), totll:1073741824(1G)\nblocksize:131072(128K), blocks:8192(8K), filesize:1073741824(1G)\n.\/newressu: sample(): writing file, filename:newressusample432.rnd\nwrote 1.00GB, 4.67MB\/sec, done!                                                                            \n.\/newressu: sample(): hashing file, filename:newressusample432.rnd, hashfilename:newressusample432.rnd.sha256, sha256:c9b1f180f9c72d2549ed29d7b4c62106192efb04a199e9344feef46376923a1d\n.\/newressu: sample(): checking sha256, filename:newressusample432.rnd\nc9b1f180f9c72d2549ed29d7b4c62106192efb04a199e9344feef46376923a1d  newressusample432.rnd\n.\/newressu: sample(): running dieharder \"dieharder -a -g 201 -f newressusample432.rnd &gt; newressusample432.rnd.dieharder 2&gt;&amp;1\"\n.\/newressu: sample(): grepping diehard problems \"grep \"WEAK\\|FAILED\" newressusample432.rnd.dieharder\"\n          sts_serial|  16|    100000|     100|0.99953101|   WEAK   \n.\/newressu: sample(): grepping last rewound count \"grep rewound newressusample432.rnd.dieharder | tail -n1\"\n# The file file_input_raw was rewound 229 times\n$ \n<\/code><\/pre>\n\n\n\n<p>Kirjoitin uuden ohjelman levynkirjoitusongelmaa varten. Se kirjoittaa levylle halutun pituisen tiedoston ja tarkistaa ett\u00e4 tieto tuli kirjoitettua oikein. Ongelmaa varten kirjoitin merkkijonosalaus (stream cipher) tyyppisen ohjelman. N\u00e4iss\u00e4 tuotetaan satunnaisbittej\u00e4 siten ett\u00e4 kaikki satunnaisuus saadaan avaimesta, ja sen perusteella annetaan n\u00e4enn\u00e4issatunnaisia merkkej\u00e4. N\u00e4in voidaan tuottaa t\u00e4ysin sama satunnaismerkkej\u00e4 sis\u00e4lt\u00e4v\u00e4 merkkijono kaksi kertaa, ensin kirjoittamiseen ja sitten tarkistukseen. T\u00e4ss\u00e4 aluksi tuo merkkijonosalaus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\n#define aDEBUG8 2\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG8\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\", cvar:\");\n  dumpline(stderr, cvarsize + 1, cvar);\n  fprintf(stderr,\", digest:\");\n  dumpline(stderr, HashLen, digest);\n  fprintf(stderr,\"\\n\");\n#endif\n}\n\n#define aDEBUG11 2\n\nstatic int streamt_pos = 0;\n\n#define STREAM_FASTER 2 \/\/ default is on\n\n#ifdef STREAM_FASTER\nstatic int streamt_rekey_rounds = 0;\n#define STREAM_REKEY_ROUNDS 1024 \/\/ 1 secure, more than one faster\n#endif\n\nvoid stream_bytes(int size, unsigned char *buffer)\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n      stream_internalbytes(streamt); \/\/ read next data bytes\n\n#ifdef DEBUG11\n      dump(stderr, \"streamt\", sizeof(streamt), streamt, 32);\n#endif\n\n#ifndef STREAM_FASTER\n      stream_internalbytes(stream_key); \/\/ change key\n#ifdef DEBUG11\n        dump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n#else\n      if(++streamt_rekey_rounds &gt;= STREAM_REKEY_ROUNDS) {\n\tstream_internalbytes(stream_key); \/\/ change key\n#ifdef DEBUG11\n\tdump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n\tstreamt_rekey_rounds = 0;\n      }\n#endif\n    }\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n  } \/\/ end of for(c = 0; c &lt; size; c++)\n\n#ifdef DEBUG11\n  dump(stderr, \"buffer\", size, buffer, 32);\n#endif\n}\n\n#define aDEBUG19 2\n#define DEBUG20 2\n\n#define STREAM_KEY_ROUNDS 1024 \/\/ should be fast enough and slow enough, now 1024\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n\n#ifdef STREAM_FASTER\n  streamt_rekey_rounds = 0;\n#endif\n  \n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n#ifdef DEBUG19\n    fprintf(stderr,\"prev:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n#endif\n\n    HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n    fprintf(stderr,\", next:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n    fprintf(stderr,\"\\n\");\n#endif \n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n#endif\n\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG20\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" key:\");\n  dumpbin(stderr, size, key);\n\n  \/\/dumpline(stderr, sizeof(key), strlen(key));\n  fprintf(stderr,\", stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Edellisess\u00e4 ohjelmassa avaimen k\u00e4sittely stream_open:issa on aika l\u00e4hell\u00e4 k\u00e4ytt\u00e4j\u00e4salasanan salakirjoitusta. Siin\u00e4 teht\u00e4v\u00e4t useammat kierrokset (t\u00e4ss\u00e4 1024) vaikuttavat toisaalta siihen kuinka nopeasti k\u00e4ytt\u00e4j\u00e4n lokkaantuminen toimii, ja toisaalta siihen kuinka nopeasti hy\u00f6kk\u00e4\u00e4j\u00e4 voi kokeilla sanalistansa sanoja. Tietysti viel\u00e4 tarvitaan mukaan satunnainen salt. Salthan on satunnainen merkkijono, joka talletetaan selv\u00e4kielisen\u00e4 salakirjoitetun salasanan kanssa ja sit\u00e4 k\u00e4ytet\u00e4\u00e4n lis\u00e4n\u00e4 salasanan salakirjoitetuksessa. Salt varmistaa ett\u00e4 sama salasana ei ole aina sama salakirjoitettuna. Tietenkin hy\u00f6kk\u00e4\u00e4j\u00e4 tarvitsee t\u00e4t\u00e4 hy\u00f6kk\u00e4yst\u00e4 varten salasanan salakirjoitettuna.<\/p>\n\n\n\n<p>Tiedostonkirjoitustestiohjelma tekee t\u00e4ll\u00e4isen tulosteen: ajossa merkkijonosalauksen merkkijono (tai avain tai salasana) on t\u00e4ss\u00e4 &#8220;kalakala&#8221;. (merkkijonosalauksista lis\u00e4\u00e4 hakusanoilla &#8220;stream cipher&#8221;)<\/p>\n\n\n\n<p>Ensimm\u00e4isell\u00e4 kierroksella kirjoitetaan ja varmistetaan tiedosto. Varmistuksessa (&#8211;verify) kirjoitettu tiedosto luetaan uudestaan ja verrataan v\u00e4litt\u00f6m\u00e4sti. Tiedostosta lasketaan tiiviste (hash). Tiivisteit\u00e4 voidaan vertailla &#8220;hashing file&#8221; -rivill\u00e4 ja &#8220;checking sha256&#8221; j\u00e4lkeisell\u00e4 rivill\u00e4. Voit tietysti tarkastaa hashin my\u00f6s $ sha256sum newressutest10.106.rnd komennolla (vaihda tiedoston nimi).<\/p>\n\n\n\n<p>Toisella kierroksella luetaan tiedosto ja vertaillaan taas &#8220;kalakala&#8221; salasanalla saatuun merkkijonoon. Exfat:in aiemmat ongelmat saa pois lis\u00e4\u00e4m\u00e4ll\u00e4 &#8211;sync ja &#8211;flush optiot. Minulle j\u00e4i kuitenkin tutina ett\u00e4 exfat:issa on viel\u00e4 joku muu ongelma. Jos haluat ihmetell\u00e4 t\u00e4t\u00e4 voit ajaa newressutest10, newressutest ja newressu &#8211;sample ohjelmaa itse. (en varmaan ole aiemmin sanonut t\u00e4t\u00e4 mutta ajamasi ohjelmat tietysti pit\u00e4\u00e4 tarkistaa ett\u00e4 ne tekev\u00e4t suurinpiirtein mit\u00e4 sanovat, ja ett\u00e4 niiss\u00e4 ei ole haitallista materiaalia). Jos ajat ohjelmia exfat levyll\u00e4 ja j\u00e4t\u00e4t &#8211;sync ja &#8211;flush optiot pois tulee erilaisia virheilmoituksia. Mielest\u00e4ni ongelmat esiintyv\u00e4t vain exfat:issa suuremmilla tiedostoilla (&gt;128g). Tavallisilla levyill\u00e4 en ole niit\u00e4 havainnut.<\/p>\n\n\n\n<p>Jos k\u00e4yt\u00e4t &#8211;verify optiota, se tarvitsee my\u00f6s &#8211;flush option.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest10 --bytes1g --flush --verify --sync\nbytes:1073741824(0x40000000)\nfilename:newressutest10.106.rnd\nmbinblocks:1024\n.\/newressutest10: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% write and verify done.\n.\/newressutest10: sample: hashing file, filename:newressutest10.106.rnd, hashfilename:newressutest10.106.rnd.sha256, sha256:8a8780a51695ae69c8e3d93e940583b42fbc9bd0f7fcf3513444d1c233da6629\n.\/newressutest10: sample: checking sha256, filename:newressutest10.106.rnd\n8a8780a51695ae69c8e3d93e940583b42fbc9bd0f7fcf3513444d1c233da6629  newressutest10.106.rnd\n.\/newressutest10: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% read and compare done.\n$ <\/code><\/pre>\n\n\n\n<p>Seuraavassa ohjelman newressutest10 l\u00e4hdekoodi: (uusi versio, jossa on muutettu merkkijonosalakirjoitusrutiineja ja comentoriviparametreja)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include \"sha256.h\"\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressutest10 version 0.4 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FILESIZE 1 * 1024 * 1024 * 1024\n#define BLOCKSIZE 1024\n#define BLOCKS FILESIZE \/ BLOCKSIZE\n\nvoid dumpbin(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    if(isprint(buf&#91;c]) &amp;&amp; buf&#91;c]!= ' ')\n      fputc(buf&#91;c], stderr);\n    else\n      fprintf(stderr,\"\\\\%02x\", buf&#91;c]);\n}\n\nvoid dumpline(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    fprintf(fp1,\"%02x\", buf&#91;c]);\n}\n\nvoid dump(FILE *fp1, unsigned char *header, int len, unsigned char *buf, int linelen)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++) {\n    if(c % linelen == 0) {\n      if(c &gt; 0)\n\tfprintf(fp1,\"\\n\");\n      fprintf(fp1,\"%-10s\", header);\n    }\n    fprintf(fp1,\" %02x\", buf&#91;c]);\n  }\n  fprintf(fp1,\"\\n\");\n  fflush(fp1);\n}\n\nvoid compareblocks(FILE *fp1, int size, unsigned char *buffer, unsigned char *buffer2)\n{\n  int c, count;\n  count = 0;\n  for(c = 0; c &lt; size; c++) {\n    if(count &gt; 31) {\n      fprintf(fp1,\"\\n\");\n      count = 0;\n    }\n    if(buffer&#91;c] == buffer2&#91;c]) {\n      fprintf(fp1,\" %02x\", buffer&#91;c]);\n      count++;\n    } else {\n      fprintf(fp1,\" %02x\/%02x\", buffer&#91;c], buffer2&#91;c]);\n      count +=2;\n    }\n  }\n}\n\nunsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n}\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}\n\nstatic unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\n#define aDEBUG8 2\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG8\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\", cvar:\");\n  dumpline(stderr, cvarsize + 1, cvar);\n  fprintf(stderr,\", digest:\");\n  dumpline(stderr, HashLen, digest);\n  fprintf(stderr,\"\\n\");\n#endif\n}\n\n#define aDEBUG11 2\n\nstatic int streamt_pos = 0;\n\n#define STREAM_FASTER 2\n\n#ifdef STREAM_FASTER\nstatic int streamt_rekey_rounds = 0;\n#define STREAM_REKEY_ROUNDS 1024 \/\/ 1 --&gt; secure, more than one --&gt; faster\n#endif\n\nvoid stream_bytes(int size, unsigned char *buffer)\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n      stream_internalbytes(streamt); \/\/ read next data bytes\n\n#ifdef DEBUG11\n      dump(stderr, \"streamt\", 32, streamt, 32);\n#endif\n      \n#ifndef STREAM_FASTER\n\n      stream_internalbytes(stream_key); \/\/ change key\n\n#ifdef DEBUG11\n      dump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n\n#else\n      if(++streamt_rekey_rounds &gt;= STREAM_REKEY_ROUNDS) {\n\tstream_internalbytes(stream_key); \/\/ change key\n#ifdef DEBUG11\n\tdump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n\tstreamt_rekey_rounds = 0;\n      }\n#endif\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n  } \/\/ end of for(c = 0; c &lt; size; c++)\n\n#ifdef DEBUG11\n  dump(stderr, \"buffer\", size, buffer, 32);\n#endif\n}\n\n#define aDEBUG19 2\n#define DEBUG20 2\n\n#define STREAM_KEY_ROUNDS 1024 \/\/ should be fast enough and slow enough, now 1024\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;\n\n#ifdef STREAM_FASTER\n  streamt_rekey_rounds = 0;\n#endif\n\n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n#ifdef DEBUG19\n    fprintf(stderr,\"prev:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n#endif\n\n    HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n    fprintf(stderr,\", next:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n    fprintf(stderr,\"\\n\");\n#endif \n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n#endif\n\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG20\n  fflush(stderr);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" key:\");\n  dumpbin(stderr, size, key);\n  fprintf(stderr,\", stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p)\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2)\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\n#define DEBUG32\n\nunsigned long long getlonglong(unsigned char *p2)\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value: %d\", digit);\n      fprintf(stderr,\", base: %d(\", base);\n      readablelonglong(stderr, base);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", ll: %llu(\", prevll);\n      readablelonglong(stderr, prevll);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", multiplier: %llu(\", multiplier);\n      readablelonglong(stderr, multiplier);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value: %d\", digit);\n    fprintf(stderr,\", base: %d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n\n  }\n\n  return(totll);\n}\n\n#define FILE_HASH 2 \/\/ on by default\n\n#ifdef FILE_HASH\n\nvoid hashfinal2string(unsigned char *hashstring, unsigned char *final)\n{\n  for(int c = 0; c &lt; HashLen; c++) {\n    sprintf(hashstring + 2 * c, \"%02x\",final&#91;c]);\n  }\n}\n\n#endif\n\nunsigned char filename&#91;128] = \"\";\n\nvoid check_firstblock()\n{\n  int count;\n  FILE *fp1;\n  static unsigned char *block = NULL;\n  static unsigned char *check_block = NULL;\n\n  if(block == NULL) {\n    if((block = malloc(BLOCKSIZE)) == NULL) {\n      fprintf(stderr,\"%s: check_firstblock(): cannot allocate memory for block\\n\", procname);\n      fflush(stderr);\n      exit(1);\n    }\n  }\n\n  if((fp1 = fopen(filename, \"r\")) == NULL) {\n    fprintf(stderr,\"%s: check_firstblock(): cannot fopen file\\n\", procname);\n    fflush(stderr);\n    exit(1);\n  }\n  count = fread(block, 1, BLOCKSIZE, fp1);\n  fclose(fp1);\n\n  if(count &lt; BLOCKSIZE) { \/\/ not a full block\n    return;\n  \n  } else if(check_block == NULL) {\n    if((check_block = malloc(BLOCKSIZE)) == NULL) {\n      fprintf(stderr,\"%s: check_firstblock(): cannot allocate memory for check_block\\n\", procname);\n      fflush(stderr);\n      exit(1);\n    }\n    memcpy(check_block, block, BLOCKSIZE);\n    dump(stderr, \"block1\", BLOCKSIZE, block, 32);\n\n  } else {\n    \n    if(memcmp(block, check_block, BLOCKSIZE)) {\n      fprintf(stderr,\"%s: check_firstblock(): first block changed\\n\", procname);\n      dump(stderr, \"block\", BLOCKSIZE, block, 32);\n      exit(1);\n    }\n  }\n}\n\n#define KILO 1024\n#define aDEBUG65 2\n#define DEBUG68\n\nint main(int argc, char *argv&#91;])\n{\n  int c, percentageline = 1, blocksize_set = 0, blocks_set = 0, filesize_set = 0;\n  unsigned long long ll, lllim, blocks = BLOCKS, filesize = FILESIZE;\n  unsigned int blocksize = BLOCKSIZE;\n  int errcount = 0, pros, prevpros, help = 0, stdoutflag = 0;\n  int writeflag = 1, verifyflag = 0, flushflag = 0, syncflag = 0, checkflag = 1, block1flag = 0;\n  unsigned char *buffer, *buffer2;\n  unsigned char key&#91;128] = \"kalakala\";\n  FILE *fp1, *fp2;\n\n  procname = argv&#91;0];\n\n#define aDEBUG46\n  \n#ifdef DEBUG46\n  stream_open(0, \"\u2680\u2681\u2682\u2683\u2684\u2685\"); \/\/ utf8  \n  stream_open(0, \"Hasta la vista, baby (Arnold Schwarzenegger, T2)\"); \/\/ pass phrase\n  stream_open(0, \"abcdefghijklmnopqrstuvwxyz\" \/\/ long password (key)\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"); \n#endif\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(c == argc - 1 &amp;&amp; !strcmp(argv&#91;c], \"-\")) {\/\/ last option hyphen\n      stdoutflag = 1; \/\/ output to stdout\n      continue;\n    }\n    \n    if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strncmp(\"-o\", argv&#91;c], 2)) { \/\/ output filename\n\tif(*(argv&#91;c] + 2) != '\\0') {\n\t  strncpy(filename, argv&#91;c] + 2, sizeof(filename));\n\t} else if(c + 1 &lt; argc) {\n\t  strncpy(filename, argv&#91;c + 1], sizeof(filename));\n\t  c++;\n\t}\n\n      } else if(!strcmp(\"--stdout\", argv&#91;c])) { \/\/ output stdout\n\tstdoutflag = 1; \/\/ output to stdout\n\t\n      } else if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c]) ) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--write\", argv&#91;c])) {\n\twriteflag = !writeflag;\n\n      } else if(!strcmp(\"--verify\", argv&#91;c])) {\n\tverifyflag = !verifyflag;\n\n      } else if(!strcmp(\"--flush\", argv&#91;c])) {\n\tflushflag = !flushflag;\n\n      } else if(!strcmp(\"--sync\", argv&#91;c])) {\n\tsyncflag = !syncflag;\n\n      } else if(!strcmp(\"--check\", argv&#91;c])) {\n\tcheckflag = !checkflag;\n\n      } else if(!strcmp(\"--block1\", argv&#91;c])) {\n\tblock1flag = !block1flag;\n\n      } else if(!strncmp(\"--key\", argv&#91;c], 5)) {\n\tif(*(argv&#91;c] + 5) != '\\0') {\n\t  strcpy(key, argv&#91;c] + 5);\n\t} else if(c + 1 &lt; argc) {\n\t  strcpy(key, argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfprintf(stderr,\"key:%s\", key);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n\n      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--blocksize\", argv&#91;c], 11)) {\n\tif(*(argv&#91;c] + 11) != '\\0') {\n\t  blocksize = getlonglong(argv&#91;c] + 11);\n\t} else if(c + 1 &lt; argc) {\n\t  blocksize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tblocksize_set = 1;\n\t\n      } else if(!strncmp(\"--blocks\", argv&#91;c], 8)) {\n\tif(*(argv&#91;c] + 8) != '\\0') {\n\t  blocks = getlonglong(argv&#91;c] + 8);\n\t} else if(c + 1 &lt; argc) {\n\t  blocks = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tblocks_set = 1;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n\n      }\n    }\n  }\n\n  if(!filesize_set)\n    filesize = blocks * blocksize;\n  else if(!blocks_set) {\n    blocks = (filesize + blocksize - 1) \/ blocksize; \/\/ round up\n    filesize = blocks * blocksize;\n  } else if(!blocksize_set) {\n    blocksize = (filesize + blocks - 1) \/ blocks; \/\/ round up\n    filesize = blocks * blocksize;\n  }\n\n#define EXFAT_FIX 2 \/\/ on for now\n  \n#ifdef EXFAT_FIX\n\n  if(blocksize &gt; KILO * KILO) { \/\/ max \"blocksize\" 1m (exfat)\n    blocksize = KILO * KILO;\n    blocks = (filesize + blocksize - 1) \/ blocksize;\n    filesize = blocks * blocksize;\n  }\n\n#endif\n  \n  if(filesize != blocks * blocksize ||\n     blocks &lt; 1 || blocksize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize \/ blocks != blocksize) { \/\/ overflow too\n    fflush(stdout);\n    fprintf(stderr,\"%s: parameter overflow\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n#ifdef DEBUG68\n  \n  fprintf(stderr,\"blocksize:%u(\", blocksize);\n  readablelonglong(stderr, blocksize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", blocks:%llu(\", blocks);\n  readablelonglong(stderr, blocks);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\\n\");\n  fflush(stderr);\n\n#endif\n  \n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\", procname);\n    fprintf(stderr,\" &#91;-o filename]\");\n    fprintf(stderr,\" &#91;--stdout]\");\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\"\\n\\t&#91;--filesize base-number-multiplier]\");\n    fprintf(stderr,\" &#91;--blocksize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--blocks base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t\");\n    fprintf(stderr,\"&#91;--write]\");\n    fprintf(stderr,\" &#91;--verify]\");\n    fprintf(stderr,\" &#91;--flush]\");\n    fprintf(stderr,\" &#91;--sync]\");\n    fprintf(stderr,\" &#91;--check]\");\n    fprintf(stderr,\" &#91;--block1]\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Options:\\n\");\n    fprintf(stderr,\"\\tWrite and check are on.\\n\");\n    fprintf(stderr,\"\\tVerify, flush, sync and block1 are off.\\n\");\n    fprintf(stderr,\"\\tOptions turn switch, so single --write means write off.\");\n    fprintf(stderr,\"\\n\\n\");\n    fprintf(stderr,\"Examples:\\n\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Typical use:\\n\"); \n    fprintf(stderr,\"\\t$ %s --filesize 128g (for regular drives)\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --filesize 128g --flush --sync (for exfat)\\n\", procname);\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Other use:\\n\");\n    fprintf(stderr,\"\\t$ %s --filesize 1g\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --filesize 8g --verify\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --filesize 64g --verify --flush\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --filesize 128g --verify --flush\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --filesize 128g --verify --flush --sync --block1\\n\", procname);\n    fprintf(stderr,\"\\t$ %s -o newressutest10.1.rnd --write --filesize 128g\\n\", procname);\n    exit(1);\n  } \/\/ end of if(help)\n\n#define aDEBUG52\n  \n#ifdef DEBUG52\n  unsigned char buffer128&#91;128];\n  stream_open(0, key);\n  stream_bytes(sizeof(buffer128), buffer128);\n  dump(stderr, \"stream\", sizeof(buffer128), buffer128, 32);\n#endif\n\n  \n  if((buffer = malloc(blocksize)) == NULL) {\n    fprintf(stderr,\"%s: cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n\n  }\n\n  if((buffer2 = malloc(blocksize)) == NULL) {\n    fprintf(stderr,\"%s: cannot allocate memory (buffer2)\\n\", procname);\n    exit(1);\n\n  }\n  \n  if(!stdoutflag &amp;&amp; filename&#91;0] == '\\0') {\n\n    \/\/ find first available filename,\n    \/\/ or empty \"slot\"\n\n    for(c = 1; c &lt;= 99999; c++) {\n      sprintf(filename, \"newressutest10.%d.rnd\", c);\n      if((fp1 = fopen(filename, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n\n#ifdef FILE_HASH\n      unsigned char filename2&#91;138];\n      sprintf(filename2,\"%s.sha256\", filename);\n      if((fp1 = fopen(filename2, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n#endif\n\n      break;\n    }\n  }\n\n  if(stdoutflag) {\n    if(isatty(STDOUT_FILENO)) { \/\/ 0=stdin, 1=stdout, 2=stderr\n      percentageline = 0;\n    }\n  }\n  \n  if(stdoutflag)\n    fprintf(stderr,\"filename:-\");\n  else\n    fprintf(stderr,\"filename:%s\",filename);\n  fprintf(stderr,\"\\n\");\n  \n#ifdef FILE_HASH\n  \n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n\n  HashInit(&amp;hash); \/\/ initialize hash\n\n#endif\n\n  if(writeflag) {\n    if(stdoutflag == 1)\n      fp1 = stdout;\n    else if((fp1 = fopen(filename, \"w\")) == NULL) { \/\/ created datafile\n      fprintf(stderr,\"%s:\", procname);\n      fprintf(stderr,\" cannot open file\");\n      fprintf(stderr,\", filename:%s\", filename);\n      fprintf(stderr,\"\\n\");\n      exit(1);\n    }\n      \n    if(verifyflag) {\n      if((fp2 = fopen(filename, \"r\")) == NULL) { \/\/ for verify file\n\tfprintf(stderr,\"%s:\", procname);\n\tfprintf(stderr,\" cannot open file\");\n\tfprintf(stderr,\", filename:%s\", filename);\n\tfprintf(stderr,\"\\n\");\n\tverifyflag = 0;\n      }\n    }\n    \n#ifdef EXFAT_FIX\n\n    int mbinblocks = (1 * KILO * KILO) \/ blocksize;\n    if(mbinblocks == 0)\n      mbinblocks = 1;\n    fprintf(stderr,\"mbinblocks:%d\\n\", mbinblocks);\n\n#endif\n    \n    prevpros = -1;\n\n    stream_open(0, key);\n    \n    lllim = (long long) filesize \/ blocksize;\n\n    for(ll = 0; ll &lt; lllim; ll++) {\n      stream_bytes(blocksize, buffer);\n      \n#ifdef DEBUG65   \n      fprintf(stderr,\"buffer    \");\n      dumpline(stderr, 32, buffer);\n      fprintf(stderr,\", block:%llu\", ll);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n#endif\n      \n#ifdef FILE_HASH\n      HashUpdate(&amp;hash, buffer, blocksize); \/\/ calculate hash\n#endif\n      \n      if(fwrite(buffer, 1, blocksize, fp1) &lt; blocksize) {\n\tfprintf(stderr,\"%s:\", procname);\n\tfprintf(stderr,\" cannot write file\");\n\tfprintf(stderr,\"\\n\");\n\texit(1);\n      }\n      \n      int flushed = 0;\n\n#ifdef EXFAT_FIX\n      \n      if(syncflag &amp;&amp; (ll % mbinblocks == 0)) { \/\/ sync every 1m\n\tif(!flushed &amp;&amp; flushflag) {\n\t  fflush(fp1);\n\t  flushed = 1;\n\t}\n\tsync();\n\t\/\/fsync(fileno(fp1));\n      }\n\n#else\n\n      if(syncflag) { \/\/ sync every 1m\n\tif(!flushed &amp;&amp; flushflag) {\n\t  fflush(fp1);\n\t  flushed = 1;\n\t}\n\tsync();\n\t\/\/fsync(fileno(fp1));\n      }\n\n#endif\n      \n      if(verifyflag) {\n\tif(!flushed &amp;&amp; flushflag) {\n\t  fflush(fp1);\n\t  flushed = 1;\n\t}\n\tif(fread(buffer2, 1, blocksize, fp2) &lt; blocksize) {\n\t  fprintf(stderr,\"%s:\", procname);\n\t  fprintf(stderr,\" cannot read file\");\n\t  fprintf(stderr,\"\\n\");\n\t  exit(1);\n\t}\t\n#ifdef DEBUG65\n\tfprintf(stderr,\"buffer2   \");\n\tdumpline(stderr, 32, buffer2);\n\tfprintf(stderr,\", block:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n#endif\n\t\n\tif(memcmp(buffer, buffer2, blocksize)) {\n\t  fflush(stderr);\n\t  fprintf(stderr,\"%s: verify error\", procname);\n\t  fprintf(stderr,\", block:%llu\", ll);\n\t  fprintf(stderr,\", offset:%llu(0x%llx)\", ll * BLOCKSIZE, ll * BLOCKSIZE);\n\t  fprintf(stderr,\", is:\");\n\t  dumpline(stderr, 16, buffer2);\n\t  fprintf(stderr,\", should be:\");\n\t  dumpline(stderr, 16, buffer);\n\t  fprintf(stderr,\"\\n\");\n\t  fflush(stderr);\n\t  if(++errcount &gt; 9)\n\t    exit(1);\n\t}\t \n      } \/\/ end of if(verifyflag)\n      \n      if(block1flag)\n\tcheck_firstblock();\n      \n      if(percentageline) {\n\tpros = (int)((double) ll \/ lllim * 1000);\n\tif(prevpros != pros) {\n\t  fflush(stdout);\n\t  prevpros = pros;\n\t  fprintf(stderr,\"\\rDone:%d.%d%%\", pros \/ 10, pros % 10);\n\t  fflush(stderr);\n\t}\n      }\n    } \/\/ end of for(ll = 0; ll &lt; lllim; ll++)\n      \n#ifdef FILE_HASH\n    HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n\n    if(syncflag) {\n      fflush(fp1);\n      sync();\n    }\n\n    if(!stdoutflag)\n      fclose(fp1);\n\n    if(syncflag) {\n      sync();\n    }\n    \n    if(verifyflag)\n      fclose(fp2);\n    \n    fprintf(stderr,\"\\rDone:100.0%%\");\n    fprintf(stderr,\" write\");\n    if(verifyflag)\n      fprintf(stderr,\" and verify\");\n    fprintf(stderr,\" done.\");\n    fprintf(stderr,\"\\n\");\n    \n#ifdef FILE_HASH\n    unsigned char hashstring&#91;2 * HashLen + 1];\n    \n    hashfinal2string(hashstring, digest);\n    \n    fprintf(stderr,\"%s: hashed file\", procname);\n    \n    if(filename&#91;0] != '\\0') {\n      fprintf(stderr,\", filename:%s\", filename);\n      \n      unsigned char filename2&#91;138];\n      \n      sprintf(filename2,\"%s.sha256\", filename);\n      \n      fprintf(stderr,\", hashfilename:%s\", filename2);\n      \n      if((fp1 = fopen(filename2, \"w\")) != NULL) {\n\tfprintf(fp1,\"%s\\n\",hashstring);\n\tfclose(fp1);\n      }\n    }      \n    fprintf(stderr,\", sha256:%s\\n\", hashstring);\n    \n    if(filename&#91;0] != '\\0') {\n      fprintf(stderr,\"%s: checking sha256\", procname);\n      fprintf(stderr,\", filename:%s\\n\", filename);\n      unsigned char command&#91;1024];\n      sprintf(command,\"sha256sum %s\", filename);\n      system(command);\n    }\n#endif\n  } \/\/ if(writeflag)\n  \n  if(!stdoutflag &amp;&amp; checkflag) {\n    if((fp2 = fopen(filename, \"r\")) != NULL) { \/\/ for reread\n\n      prevpros = -1;\n      lllim = (long long) filesize \/ blocksize;\n\n      stream_open(0, key);\n    \n      for(ll = 0; ll &lt; lllim; ll++) {\n\tstream_bytes(blocksize, buffer);\n\n\tif(fread(buffer2, 1, blocksize, fp2) &lt; blocksize) {\n\t  fprintf(stderr,\"%s:\", procname);\n\t  fprintf(stderr,\" cannot read file\");\n\t  fprintf(stderr,\"\\n\");\n\t  exit(1);\n\t}\n\n#ifdef DEBUG65\n\tfflush(stdout);\n\tfprintf(stderr,\"bbuffer   \");\n\tdumpline(stderr, 32, buffer);\n\tfprintf(stderr,\", block:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfprintf(stderr,\"bbuffer2  \");\n\tdumpline(stderr, 32, buffer2);\n\tfprintf(stderr,\", block:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n#endif\n\n\tif(memcmp(buffer, buffer2, blocksize)) {\n\t  fflush(stdout);\n\t  fprintf(stderr,\"%s: check error\", procname);\n\t  fprintf(stderr,\", block:%llu\", ll);\n\t  fprintf(stderr,\", offset:%llu(0x%llu)\", ll * BLOCKSIZE, ll * BLOCKSIZE);\n\t  fprintf(stderr,\", data:\");\n\t  dumpline(stderr, 32, buffer2);\n\t  fprintf(stderr,\", should be:\");\n\t  dumpline(stderr, 32, buffer);\n\t  fprintf(stderr,\"\\n\");\n\t  compareblocks(stderr, blocksize, buffer, buffer2);\n\t  fprintf(stderr,\"\\n\");\n\t  fflush(stderr);\n\t  if(++errcount &gt; 9)\n\t    exit(1);\n\t}\n\n\tif(block1flag)\n\t  check_firstblock();\n\t\n\tpros = (int)((double) ll \/ lllim * 1000);\n\tif(prevpros != pros) {\n\t  fflush(stdout);\n\t  prevpros = pros;\n\t  fprintf(stderr,\"\\rDone:%d.%d%%\", pros \/ 10, pros % 10);\n\t  fflush(stderr);\n\t}\t\n      } \/\/ end of for(ll = 0; ll &lt; lllim; ll++)\n      \n      fclose(fp2);\n      fflush(stdout);\n      fprintf(stderr,\"\\rDone:100.0%%\"); \n      fprintf(stderr,\" read and compare\");\n      fprintf(stderr,\" done.\");\n      fprintf(stderr,\"\\n\");\n    } \/\/ end of if((fp2 = fopen(filename, \"r\")) != NULL)\n  } \/\/ end of if(checkflag)\n}<\/code><\/pre>\n\n\n\n<p>My\u00f6s joihinkin postin aiempiin testailuohjelmiin (newressutest9 ja newressutest) on lis\u00e4tty flush ja sync, p\u00e4ivit\u00e4n niiden versiot t\u00e4ss\u00e4 postissa uudempiin.<\/p>\n\n\n\n<p>Lis\u00e4tty uusi testiohjelma newressutest12, joka kirjoittaa ja lukee kiinte\u00e4npituisia tietueita. T\u00e4ss\u00e4 ohjelman tuloste: T\u00e4ss\u00e4 tulostetaan 1048576 (1m) rivi\u00e4 jotka sis\u00e4lt\u00e4v\u00e4t 10 merkki\u00e4 tietoa. Rivit tulostetaan heksajonona, joten yksi tulostettava rivi on 10 * 2 + 1 = 21 merkki\u00e4 pitk\u00e4. Tiedostosta tulee 1m * 21 = 21m kokoinen. T\u00e4ss\u00e4 tiedosto on kirjoitettu ja varmistettu (vaihe 1) ja luettu ja tarkistettu (vaihe 2). Muista lis\u00e4t\u00e4 &#8211;flush ja &#8211;sync exfat levyille.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest12 --bytes10 --lines1m --verify --flush\nbase:10, multiplier:1, prevll:10, ll:10, totll:10\nbase:10, multiplier:1048576, prevll:1, ll:1048576, totll:1048576\nlines:1048576(1M), bytes:10(10B), linesize:21(21B), filesize:22020096(21M)\nfilename:newressutest12.108.rnd\nmbinlines:49932\n.\/newressutest12: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% write and verify done.\n.\/newressutest12: sample: hashing file, filename:newressutest12.108.rnd, hashfilename:newressutest12.108.rnd.sha256, sha256:a328ce8d2c4d98bb4ebf8ee3f8ac6d79e561722105789ceea68ae8837b974072\n.\/newressutest12: sample: checking sha256, filename:newressutest12.108.rnd\na328ce8d2c4d98bb4ebf8ee3f8ac6d79e561722105789ceea68ae8837b974072  newressutest12.108.rnd\n.\/newressutest12: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% read and compare done.\n$ <\/code><\/pre>\n\n\n\n<p>Seuraavassa p\u00e4tk\u00e4 tulostettua tiedostoa: T\u00e4ss\u00e4 on tulostettu 10 merkin pituisia tietueita 10 kappaletta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest12 --bytes10 --lines10\nbase:10, multiplier:1, prevll:10, ll:10, totll:10\nbase:10, multiplier:1, prevll:10, ll:10, totll:10\nlines:10(10B), bytes:10(10B), linesize:21(21B), filesize:210(210B)\nfilename:newressutest12.109.rnd\nmbinlines:49932\n.\/newressutest12: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% write done.\n.\/newressutest12: sample: hashing file, filename:newressutest12.109.rnd, hashfilename:newressutest12.109.rnd.sha256, sha256:d57ad8172aa54ba800829370a98a241a19777aa6759401e6ff8b5577fcae7729\n.\/newressutest12: sample: checking sha256, filename:newressutest12.109.rnd\nd57ad8172aa54ba800829370a98a241a19777aa6759401e6ff8b5577fcae7729  newressutest12.109.rnd\n.\/newressutest12: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% read and compare done.\n$ cat newressutest12.109.rnd\nc0d1bc849d6fbb01fe79\n507f611bfb4b0f739177\nf574c12575e932b44ae3\n29c32527df32c830651d\neb4880d6183b3cf1b3c2\na8dd883ba01e469d575c\ncd8686453516ecf6251f\n82adacdc30d74b31560a\n7ccc5e834de655424463\nc1e0bf91dd1c2ff14998\n$ \n<\/code><\/pre>\n\n\n\n<p>Seuraavalla voi testata piipun (&#8216;|&#8217;) toimivuutta: datasta lasketun tiivisteen pit\u00e4\u00e4 m\u00e4ts\u00e4t\u00e4 $sha256sum komennon tulostaman tiivisteen kanssa (c255de-alkuinen merkkijono).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest12 --bytes16 --lines40g --stdout | sha256sum\nstring:'16', base:10, multiplier:1, prevll:16, ll:16, totll:16\nstring:'40g', base:10, multiplier:1073741824, prevll:40, ll:42949672960, totll:42949672960\nlines:42949672960(40G), bytes:16(16B), linesize:33(33B), filesize:1417339207680(~1T)\nfilename:\nmbinlines:31775\n.\/newressutest12: stream_open(): key:kalakala, stream_key:448cd1f8dea2f75d469e1f265cbc2658426121577335348a11c5ec7c25c07bf1\nDone:100.0% write done.\n.\/newressutest12: sample: hashing file, filename:, hashfilename:.sha256, sha256:c255de89c865c957bccc648ab7fbd9327eec338f36dfb96112ca3801fbbf2b71\nc255de89c865c957bccc648ab7fbd9327eec338f36dfb96112ca3801fbbf2b71  -\n$<\/code><\/pre>\n\n\n\n<p>Ja varsinainen ohjelma newressutest12.c:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include \"sha256.h\"\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressutest12 version 0.7 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2023 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FILESIZE 81 * 1024 * 1024\n#define BINSIZE 40 \/\/ bytes per line\n#define LINESIZE 81 \/\/ BINSIZE * 2 + 1\n#define LINES 1 * 1024 * 1024\n\n#define BLOCKSIZE 1024\n\nint help = 0;\n\nvoid dumpbin(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    if(isprint(buf&#91;c]) &amp;&amp; buf&#91;c]!= ' ')\n      fputc(buf&#91;c], stderr);\n    else\n      fprintf(stderr,\"\\\\%02x\", buf&#91;c]);\n}\n\nvoid dumpline(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    fprintf(fp1,\"%02x\", buf&#91;c]);\n}\n\nvoid dump(FILE *fp1, unsigned char *header, int len, unsigned char *buf, int linelen)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++) {\n    if(c % linelen == 0) {\n      if(c &gt; 0)\n\tfprintf(fp1,\"\\n\");\n      fprintf(fp1,\"%-10s\", header);\n    }\n    fprintf(fp1,\" %02x\", buf&#91;c]);\n  }\n  fprintf(fp1,\"\\n\");\n  fflush(fp1);\n}\n\nvoid compareblocks(FILE *fp1, int size, unsigned char *buffer, unsigned char *buffer2)\n{\n  int c, count;\n\n  count = 0;\n  for(c = 0; c &lt; size; c++) {\n    if(count &gt; 31) {\n      fprintf(fp1,\"\\n\");\n      count = 0;\n    }\n    if(buffer&#91;c] == buffer2&#91;c]) {\n      fprintf(fp1,\" %02x\", buffer&#91;c]);\n      count++;\n    } else {\n      fprintf(fp1,\" %02x\/%02x\", buffer&#91;c], buffer2&#91;c]);\n      count +=2;\n    }\n  }\n}\n\nunsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n}\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}\n\nstatic unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\n#define aDEBUG8 2\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG8\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\", cvar:\");\n  dumpline(stderr, cvarsize + 1, cvar);\n  fprintf(stderr,\", digest:\");\n  dumpline(stderr, HashLen, digest);\n  fprintf(stderr,\"\\n\");\n#endif\n}\n\n#define aDEBUG11 2\n\nstatic int streamt_pos = 0;\n\n#define STREAM_FASTER 2 \/\/ default is on\n\n#ifdef STREAM_FASTER\nstatic int streamt_rekey_rounds = 0;\n#define STREAM_REKEY_ROUNDS 1024 \/\/ 1 secure, more than one faster\n#endif\n\nvoid stream_bytes(int size, unsigned char *buffer)\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n      stream_internalbytes(streamt); \/\/ read next data bytes\n\n#ifdef DEBUG11\n      dump(stderr, \"streamt\", sizeof(streamt), streamt, 32);\n#endif\n\n#ifndef STREAM_FASTER\n\n      stream_internalbytes(stream_key); \/\/ change key\n\n#ifdef DEBUG11\n      dump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n\n#else\n      if(++streamt_rekey_rounds &gt;= STREAM_REKEY_ROUNDS) {\n\tstream_internalbytes(stream_key); \/\/ change key\n\n#ifdef DEBUG11\n\tdump(stderr, \"rekey\", 32, stream_key, 32);\n#endif\n\n\tstreamt_rekey_rounds = 0;\n      }\n#endif\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n  } \/\/ end of for(c = 0; c &lt; size; c++)\n\n#ifdef DEBUG11\n  dump(stderr, \"buffer\", size, buffer, 32);\n#endif\n}\n\n#define aDEBUG19 2\n#define DEBUG20 2\n\n#define STREAM_KEY_ROUNDS 1024 \/\/ should be fast enough and slow enough, now 1024\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n\n#ifdef STREAM_FASTER\n  streamt_rekey_rounds = 0;\n#endif\n  \n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n#ifdef DEBUG19\n    fprintf(stderr,\"prev:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n#endif\n\n    HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n    fprintf(stderr,\", next:\");\n    dumpline(stderr, sizeof(stream_key), stream_key);\n    fprintf(stderr,\"\\n\");\n#endif \n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#ifdef DEBUG19\n  fprintf(stderr,\"stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n#endif\n\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n#ifdef DEBUG20\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" key:\");\n  dumpbin(stderr, size, key);\n\n  fprintf(stderr,\", stream_key:\");\n  dumpline(stderr, sizeof(stream_key), stream_key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p)\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2)\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n  \n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\n#define DEBUG32 2\n\nunsigned long long getlonglong(unsigned char *p2)\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value:%d\", digit);\n      fprintf(stderr,\", base:%d(\", base);\n      readablelonglong(stderr, base);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", prevll:%llu(\", prevll);\n      readablelonglong(stderr, prevll);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", ll:%llu(\", ll);\n      readablelonglong(stderr, ll);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", multiplier:%llu(\", multiplier);\n      readablelonglong(stderr, multiplier);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n      exit(1);\n    }\n\n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value:%d\", digit);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  return(totll);\n}\n\n#define FILE_HASH 2 \/\/ on by default\n\n#ifdef FILE_HASH\n\nvoid hashfinal2string(unsigned char *hashstring, unsigned char *final)\n{\n  for(int c = 0; c &lt; HashLen; c++) {\n    sprintf(hashstring + 2 * c, \"%02x\", final&#91;c]);\n  }\n}\n\n#endif\n\nunsigned char filename&#91;128] = \"\";\n\nvoid check_firstblock()\n{\n  int count;\n  FILE *fp1;\n  static unsigned char *block = NULL;\n  static unsigned char *check_block = NULL;\n\n  if(block == NULL) {\n    if((block = malloc(BLOCKSIZE)) == NULL) {\n      fprintf(stderr,\"%s: check_firstblock(): cannot allocate memory for block\\n\", procname);\n      fflush(stderr);\n      exit(1);\n    }\n  }\n\n  if((fp1 = fopen(filename, \"r\")) == NULL) {\n    fprintf(stderr,\"%s: check_firstblock(): cannot fopen file\\n\", procname);\n    fflush(stderr);\n    exit(1);\n  }\n  count = fread(block, 1, BLOCKSIZE, fp1);\n  fclose(fp1);\n\n  if(count &lt; BLOCKSIZE) { \/\/ not a full block\n    return;\n\n  } else if(check_block == NULL) { \/\/ read and save original block\n    if((check_block = malloc(BLOCKSIZE)) == NULL) {\n      fprintf(stderr,\"%s: check_firstblock(): cannot allocate memory for check_block\\n\", procname);\n      fflush(stderr);\n      exit(1);\n    }\n    memcpy(check_block, block, BLOCKSIZE);\n    dump(stderr, \"block1\", BLOCKSIZE, block, 32);\n    \n  } else { \/\/ compare to original block\n    if(memcmp(block, check_block, BLOCKSIZE)) {\n      fprintf(stderr,\"%s: check_firstblock(): first block changed\\n\", procname);\n      dump(stderr, \"block\", BLOCKSIZE, block, 32);\n      exit(1);\n    }\n  }\n}\n\n#define aDEBUG65 2\n#define DEBUG69 2\n\nint main(int argc, char *argv&#91;])\n{\n  int c, percentageline = 1;\n  int filesize_set = 0, binsize_set = 0, linesize_set = 0, lines_set = 0;\n  unsigned long long ll, filesize = FILESIZE, lines = LINES;\n  unsigned int binsize = BINSIZE, linesize = LINESIZE;\n  int errcount = 0, pros, prevpros;\n  int writeflag = 1, stdoutflag = 0, verifyflag = 0, flushflag = 0;\n  int syncflag = 0, checkflag = 1, block1flag = 0;\n  unsigned char *binbuffer, *buffer, *buffer2;\n  unsigned char key&#91;128] = \"kalakala\";\n  FILE *fp1, *fp2;\n\n  procname = argv&#91;0];\n\n#define aDEBUG46 2\n\n#ifdef DEBUG46\n  ll = 1;\n  for(;;) {\n    fprintf(stderr,\"ll:%llu\", ll);\n    fprintf(stderr,\", readablelonglong:\");\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\"\\n\");\n    unsigned long long prevll = ll;\n    ll *= 2;\n    if(ll \/ 2 != prevll)\n      break;\n  }\n#endif\n\n#define aDEBUG48 2\n\n#ifdef DEBUG48\n  stream_open(0, \"\u2680\u2681\u2682\u2683\u2684\u2685\"); \/\/ utf8  \n  stream_open(0, \"Hasta la vista, baby (Arnold Schwarzenegger, T2)\"); \/\/ pass phrase\n  stream_open(0, \"abcdefghijklmnopqrstuvwxyz\" \/\/ long password (key)\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"); \n#endif\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(c == argc - 1 &amp;&amp; !strcmp(argv&#91;c], \"-\")) { \/\/ last option hyphen\n      stdoutflag = 1; \/\/ output to stdout\n      continue;\n    }\n    \n    if(!strncmp(\"-\",argv&#91;c], 1)) { \/\/ option starting with hyphen\n\n      if(!strncmp(\"-o\", argv&#91;c], 2)) { \/\/ output filename\n\tif(*(argv&#91;c] + 2) != '\\0') {\n\t  strncpy(filename, argv&#91;c] + 2, sizeof(filename));\n\t} else if(c + 1 &lt; argc) {\n\t  strncpy(filename, argv&#91;c + 1], sizeof(filename));\n\t  c++;\n\t}\n\n      } else if(!strcmp(\"--stdout\", argv&#91;c])) { \/\/ output stdout\n\tstdoutflag = 1; \/\/ output to stdout\n\t\n      } else if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c]) ) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--write\", argv&#91;c])) {\n\twriteflag = !writeflag;\n\n      } else if(!strcmp(\"--verify\", argv&#91;c])) {\n\tverifyflag = !verifyflag;\n\n      } else if(!strcmp(\"--flush\", argv&#91;c])) {\n\tflushflag = !flushflag;\n\n      } else if(!strcmp(\"--sync\", argv&#91;c])) {\n\tsyncflag = !syncflag;\n\n      } else if(!strcmp(\"--check\", argv&#91;c])) {\n\tcheckflag = !checkflag;\n\n      } else if(!strcmp(\"--block1\", argv&#91;c])) {\n\tblock1flag = !block1flag;\n\n      } else if(!strncmp(\"--key\", argv&#91;c], 5)) {\n\tif(*(argv&#91;c] + 5) != '\\0') {\n\t  strcpy(key, argv&#91;c] + 5);\n\t} else if(c + 1 &lt; argc) {\n\t  strcpy(key, argv&#91;c +1]);\n\t}\n\tfprintf(stderr,\"key:%s\", key);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n\n      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--linesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  linesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  linesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlinesize_set = 1;\n\t\n      } else if(!strncmp(\"--lines\", argv&#91;c], 7)) {\n\tif(*(argv&#91;c] + 7) != '\\0') {\n\t  lines = getlonglong(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  lines = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlines_set = 1;\n\n      } else if(!strncmp(\"--binsize\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  binsize = getlonglong(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc) {\n\t  binsize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tbinsize_set = 1;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n\n      }\n    } \/\/ end of if(!strncmp(\"-\",argv&#91;c], 1\n  } \/\/ end of for(c = 1; c &lt; argc; c++\n\n  if(!linesize_set)\n    linesize = binsize * 2 + 1;\n  else if(!binsize_set)\n    binsize = (linesize - 1) \/ 2;\n\n  if(linesize != binsize * 2 + 1 ||\n     linesize &lt; 3 || binsize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", binsize:%u(\", binsize);\n    readablelonglong(stderr, binsize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n    \n  if(!filesize_set)\n    filesize = lines * linesize;\n  else if(!lines_set) {\n    lines = (filesize + linesize - 1) \/ linesize; \/\/ round up\n    filesize = lines * linesize;\n  } else if(!linesize_set) {\n    linesize = (filesize + lines - 1) \/ lines; \/\/ round up\n    filesize = lines * linesize;\n  }\n\n#define aEXFAT_FIX 2\n\n#ifdef EXFAT_FIX\n  \n  if(linesize &gt;= KILO * KILO) { \/\/ max linesize 1m (exfat)\n    linesize = KILO * KILO - 1;\n    binsize = (linesize - 1) \/ 2;\n    lines = (filesize + linesize - 1) \/ linesize;\n    filesize = lines * linesize;\n  }\n\n#endif\n  \n  if(filesize != lines * linesize ||\n     lines &lt; 1 || linesize &lt; 3) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize \/ lines != linesize) { \/\/ check for overflow too\n    fflush(stdout);\n    fprintf(stderr,\"%s: parameter overflow\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\", procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;-o filename]\");\n    fprintf(stderr,\" &#91;--stdout]\");\n    fprintf(stderr,\"\\n\\t&#91;--filesize base-number-multiplier]\"); \n    fprintf(stderr,\" &#91;--linesize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--lines base-number-multiplier]\");\n    fprintf(stderr,\" &#91;--binsize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--write]\");\n    fprintf(stderr,\" &#91;--verify]\");\n    fprintf(stderr,\" &#91;--flush]\");\n    fprintf(stderr,\" &#91;--sync]\");\n    fprintf(stderr,\" &#91;--check]\");\n    fprintf(stderr,\" &#91;--block1]\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Options:\\n\");\n    fprintf(stderr,\"\\tWrite and check are on.\\n\");\n    fprintf(stderr,\"\\tVerify, flush, sync and block1 are off.\\n\");\n    fprintf(stderr,\"\\tOptions turn switch, so single --write means write off.\");\n    fprintf(stderr,\"\\n\\n\");\n    fprintf(stderr,\"Examples:\\n\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Typical use:\\n\"); \n    fprintf(stderr,\"\\t$ %s --lines 128m (for regular drives)\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --lines 128m --flush --sync (for exfat)\\n\", procname);\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Other use:\\n\");\n    fprintf(stderr,\"\\t$ %s --lines 1m\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --lines 8m --verify\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --lines 64m --verify --flush\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --lines 128m --verify --flush\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --lines 128m --verify --flush --sync --block1\\n\", procname);\n    fprintf(stderr,\"\\t$ %s newressutest12.1.rnd --write --lines 128m\\n\", procname);\n    exit(1);\n  } \/\/ end of if(help)\n\n#ifdef DEBUG69\n\n  \/\/ print filesize parameters\n  \n  fprintf(stderr,\"lines:%llu(\", lines);\n  readablelonglong(stderr, lines);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", binsize:%u(\", binsize);\n  readablelonglong(stderr, binsize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", linesize:%u(\", linesize);\n  readablelonglong(stderr, linesize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\\n\");\n  fflush(stderr);\n\n#endif\n    \n  \n  unsigned int dumplinelength = 32;\n  if(dumplinelength &gt; linesize)\n    dumplinelength = linesize;\n\n  if((binbuffer = malloc(binsize)) == NULL) {\n    fprintf(stderr,\"%s: cannot allocate memory (binbuffer)\\n\", procname);\n    exit(1);\n  }\n\n  if((buffer = malloc(linesize)) == NULL) {\n    fprintf(stderr,\"%s: cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n  }\n\n  if((buffer2 = malloc(linesize)) == NULL) {\n    fprintf(stderr,\"%s: cannot allocate memory (buffer2)\\n\", procname);\n    exit(1);\n  }\n\n#define aDEBUG52\n  \n#ifdef DEBUG52\n  unsigned char buffer128&#91;128];\n  stream_open(0, key);\n  stream_bytes(sizeof(buffer128), buffer128);\n  dump(stderr, \"stream\", sizeof(buffer128), buffer128, 32);\n#endif\n  \n  if(!stdoutflag &amp;&amp; filename&#91;0] == '\\0') {\n\n    \/\/ find first available filename,\n    \/\/ or empty \"slot\"\n\n    for(c = 1; c &lt;= 99999; c++) {\n      sprintf(filename, \"newressutest12.%d.rnd\", c);\n      if((fp1 = fopen(filename, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n\n#ifdef FILE_HASH\n      unsigned char filename2&#91;138];\n      sprintf(filename2,\"%s.sha256\", filename);\n      if((fp1 = fopen(filename2, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n#endif\n\n      break;\n    }\n  }\n\n  if(stdoutflag) {\n    if(isatty(STDOUT_FILENO)) { \/\/ 0=stdin, 1=stdout, 2=stderr\n      percentageline = 0;\n    }\n  }\n  \n  if(stdoutflag)\n    fprintf(stderr,\"filename:-\");\n  else\n    fprintf(stderr,\"filename:%s\",filename);\n  fprintf(stderr,\"\\n\");\n  \n#ifdef FILE_HASH\n  \n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n\n  HashInit(&amp;hash); \/\/ initialize hash\n\n#endif\n\n  if(writeflag) {\n    if(stdoutflag == 1)\n      fp1 = stdout;\n    else if((fp1 = fopen(filename, \"w\")) == NULL) { \/\/ created datafile\n      fprintf(stderr,\"%s:\", procname);\n      fprintf(stderr,\" cannot open file\");\n      fprintf(stderr,\", filename:%s\", filename);\n      fprintf(stderr,\"\\n\");\n      exit(1);\n    }\n\n    if(verifyflag) {\n      if((fp2 = fopen(filename, \"r\")) == NULL) { \/\/ for verify file\n\tfprintf(stderr,\"%s:\", procname);\n\tfprintf(stderr,\" cannot open file\");\n\tfprintf(stderr,\", filename:%s\", filename);\n\tfprintf(stderr,\"\\n\");\n\tverifyflag = 0;\n      }\n    }\n    \n#ifdef EXFAT_FIX\n\n    int mbinlines = (KILO * KILO) \/ linesize;\n    if(mbinlines == 0)\n      mbinlines = 1;\n    fprintf(stderr,\"mbinlines:%d\\n\", mbinlines);\n\n#endif\n    \n    prevpros = -1;\n\n    stream_open(0, key);\n    \n    for(ll = 0; ll &lt; lines; ll++) {\n      stream_bytes(binsize, binbuffer);\n      \n      for(c = 0; c &lt; binsize; c++)\n\tsprintf(buffer + c * 2, \"%02x\", binbuffer&#91;c]);\n      buffer&#91;linesize - 1] = '\\n';\n      \n#ifdef DEBUG65   \n      fprintf(stderr,\"buffer    \");\n      dumpline(stderr, dumplinelength, buffer);\n      fprintf(stderr,\", block:%llu\", ll);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n#endif\n      \n#ifdef FILE_HASH\n      HashUpdate(&amp;hash, buffer, linesize); \/\/ calculate hash\n#endif\n      \n      if(fwrite(buffer, 1, linesize, fp1) &lt; linesize) {\n\tfprintf(stderr,\"%s:\", procname);\n\tfprintf(stderr,\" cannot write file\");\n\tfprintf(stderr,\"\\n\");\n\texit(1);\n      }\n      \n      int flushed = 0;\n      \n#ifdef EXFAT_FIX\n      if(syncflag &amp;&amp; (ll % mbinlines == 0)) { \/\/ sync every 1m (exfat)\n\tif(!flushed &amp;&amp; flushflag) {\n\t  fflush(fp1);\n\t  flushed = 1;\n\t}\n\tsync();\n\t\/\/fsync(fileno(fp1));\n      }\n#else\n      if(flushflag) {\n\tfflush(fp1);\n\tflushed = 1;\n      }\n      if(syncflag) {\n\tsync();\n      }\n#endif\n      if(verifyflag) {\n\tif(!flushed &amp;&amp; flushflag) {\n\t  fflush(fp1);\n\t  flushed = 1;\n\t}\n\tif(fread(buffer2, 1, linesize, fp2) &lt; linesize) {\n\t  fprintf(stderr,\"%s:\", procname);\n\t  fprintf(stderr,\" cannot read file\");\n\t  fprintf(stderr,\"\\n\");\n\t  exit(1);\n\t}\n\t\n#ifdef DEBUG65\n\tfprintf(stderr,\"buffer2   \");\n\tdumpline(stderr, dumplinelength, buffer2);\n\tfprintf(stderr,\", block:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n#endif\n\t\n\tif(memcmp(buffer, buffer2, linesize)) {\n\t  fflush(stdout);\n\t  fprintf(stderr,\"%s: verify error\", procname);\n\t  fprintf(stderr,\", lines:%llu\", ll);\n\t  fprintf(stderr,\", offset:%llu(0x%llx)\", ll * LINESIZE, ll * LINESIZE);\n\t  fprintf(stderr,\", is:\");\n\t  dumpline(stderr, dumplinelength, buffer2);\n\t  fprintf(stderr,\", should be:\");\n\t  dumpline(stderr, dumplinelength, buffer);\n\t  fprintf(stderr,\"\\n\");\n\t  fflush(stderr);\n\t  if(++errcount &gt; 9)\n\t    exit(1);\n\t}\t \n      } \/\/ end of if(verifyflag)\n      \n      if(block1flag)\n\tcheck_firstblock();\n\n      if(percentageline) {\n\tpros = (int)((double) ll \/ lines * 1000);\n\tif(prevpros != pros) {\n\t  fflush(stdout);\n\t  prevpros = pros;\n\t  fprintf(stderr,\"\\rDone:%d.%d%%\", pros \/ 10, pros % 10);\n\t  fflush(stderr);\n\t}\n      }\n    } \/\/ end of for(ll = 0; ll &lt; lines; ll++)\n    \n#ifdef FILE_HASH\n    HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n    \n    fprintf(stderr,\"\\rDone:100.0%%\");\n    fprintf(stderr,\" write\");\n    if(verifyflag)\n      fprintf(stderr,\" and verify\");\n    fprintf(stderr,\" done.\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    \n    fflush(fp1);\n    sync();\n    if(!stdoutflag)\n      fclose(fp1);\n    \n    if(verifyflag)\n      fclose(fp2);\n    \n#ifdef FILE_HASH\n    unsigned char hashstring&#91;2 * HashLen + 1];\n    \n    hashfinal2string(hashstring, digest);\n    \n    fprintf(stderr,\"%s: hashed file\", procname);\n\n    if(filename&#91;0] != '\\0') {\n      fprintf(stderr,\", filename:%s\", filename);\n\n      unsigned char filename2&#91;138];\n\n      sprintf(filename2,\"%s.sha256\", filename);\n    \n      fprintf(stderr,\", hashfilename:%s\", filename2);\n\n      if((fp1 = fopen(filename2, \"w\")) != NULL) {\n\tfprintf(fp1,\"%s\\n\", hashstring);\n\tfclose(fp1);\n      }\n    }\n    fprintf(stderr,\", sha256:%s\\n\", hashstring);\n\n    if(filename&#91;0] != '\\0') {\n      fprintf(stderr,\"%s: checking sha256\", procname);\n      fprintf(stderr,\", filename:%s\\n\", filename);\n      unsigned char command&#91;1024];\n      sprintf(command,\"sha256sum %s\", filename);\n      system(command);\n    }\n#endif\n  } \/\/ if(writeflag)\n  \n  if(!stdoutflag &amp;&amp; checkflag) {\n    if((fp2 = fopen(filename, \"r\")) != NULL) { \/\/ for reread\n\n      prevpros = -1;\n\n      stream_open(0, key);\n    \n      for(ll = 0; ll &lt; lines; ll++) {\n\tstream_bytes(binsize, binbuffer);\n\t\n\tfor(c = 0; c &lt; binsize; c++)\n\t  sprintf(buffer + c * 2, \"%02x\", binbuffer&#91;c]);\n\tbuffer&#91;linesize - 1] = '\\n';\n\t\n\tif(fread(buffer2, 1, linesize, fp2) &lt; linesize) {\n\t  fprintf(stderr,\"%s:\", procname);\n\t  fprintf(stderr,\" cannot read file\");\n\t  fprintf(stderr,\"\\n\");\n\t  exit(1);\n\t}\n\n#ifdef DEBUG65\n\tfflush(stderr);\n\tfprintf(stderr,\"bbuffer   \");\n\tdumpline(stderr, dumplinelength, buffer);\n\tfprintf(stderr,\", line:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfprintf(stderr,\"bbuffer2  \");\n\tdumpline(stderr, dumplinelength, buffer2);\n\tfprintf(stderr,\", line:%llu\", ll);\n\tfprintf(stderr,\"\\n\");\n\tfflush(stderr);\n#endif\n\n\tif(memcmp(buffer, buffer2, linesize)) {\n\t  fflush(stdout);\n\t  fprintf(stderr,\"%s: check error\", procname);\n\t  fprintf(stderr,\", line:%llu\", ll);\n\t  fprintf(stderr,\", offset:%llu(0x%llx)\", ll * linesize, ll * linesize);\n\t  fprintf(stderr,\", data:\");\n\t  dumpline(stderr, dumplinelength, buffer2);\n\t  fprintf(stderr,\", should be:\");\n\t  dumpline(stderr, dumplinelength, buffer);\n\t  fprintf(stderr,\"\\n\");\n\t  compareblocks(stderr, linesize, buffer, buffer2);\n\t  fprintf(stderr,\"\\n\");\n\t  fflush(stderr);\n\t  if(++errcount &gt; 9)\n\t    exit(1);\n\t}\n\n\tif(block1flag)\n\t  check_firstblock();\n\t\n\tpros = (int)((double) ll \/ lines * 1000);\n\tif(prevpros != pros) {\n\t  fflush(stdout);\n\t  prevpros = pros;\n\t  fprintf(stderr,\"\\rDone:%d.%d%%\", pros \/ 10, pros % 10);\n\t  fflush(stderr);\n\t}\n      } \/\/ end of for(ll = 0; ll &lt; lllim; ll++)\n      \n      fclose(fp2);\n      fflush(stdout);\n      fprintf(stderr,\"\\rDone:100.0%%\"); \n      fprintf(stderr,\" read and compare\");\n      fprintf(stderr,\" done.\");\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n    } \/\/ end of if((fp2 = fopen(filename, \"r\")) != NULL)\n  } \/\/ end of if(checkflag)\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty save_path, exists_path ja set_path, joiden k\u00e4yt\u00f6st\u00e4 voit katsoa esimerkin DEBUG72 koodista. T\u00e4ss\u00e4 kuitenkin viel\u00e4 koodit niille:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG25\n\nvoid save_path(int path_length, unsigned char *path)\n{\n  if((getcwd(path, path_length)) == NULL) {\n    fprintf(stdout,\"%s: save_path(): cannot get working directory (getcwd)\\n\",\n\t    procname);\n  }\n#ifdef DEBUG25\n  fprintf(stdout,\"%s: save_path(): saved current path (getcwd), path = %s\\n\",\n\t  procname,path);\n#endif\n}\n\nint exists_path(unsigned char *path)\n{\n  FILE *fp1;\n  \n  if((fp1 = fopen(path,\"r\")) != NULL) {\n    fclose(fp1);\n    return(1);\n  } else\n    return(0);\n}\n\nvoid set_path(unsigned char *path)\n{\n if(chdir(path) != 0) {\n    fprintf(stdout,\"%s: set_path(): cannot change directory (chdir())\\n\",\n\t    procname);\n  }\n#ifdef DEBUG25\n  fprintf(stdout,\"%s: set_path(): set path (chdir()), path = %s\\n\",\n\t  procname,path);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 esimerkki k\u00e4yt\u00f6st\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef DEBUG72\n  if(flagint) {\n    unsigned char savepath&#91;128] = \".\/\";\n    \/\/fprintf(stderr,\"%s: Running integrity test(s)...\", procname);\n    fflush(stderr);\n    save_path(sizeof(savepath), savepath);\n\n    if(!strncmp(procname, \"\/bin\/newressu\", 13) &amp;&amp; exists_path(\"\/var\/ressu\")) {\n      set_path(\"\/var\/ressu\");\n      fprintf(stderr,\"%s: procname '\/bin\/newressu', path exists '%s', path set\\n\",\n\t      procname, \"\/var\/ressu\");\n      fflush(stderr);\n\n    } else if(exists_path(\"\/var\/ressu\")) {\n      set_path(\"\/var\/ressu\");\n      fprintf(stderr,\"%s: path exists '%s', set\\n\",\n\t      procname,\"\/var\/ressu\");\n      fflush(stderr);\n\n    } else if(exists_path(\"\/var\/newressu\")) {\n      set_path(\"\/var\/newressu\");\n      fprintf(stderr,\"%s: path exists '%s', set\\n\",\n\t      procname,\"\/var\/newressu\");\n      fflush(stderr);\n\n    } else if(exists_path(\"dkala\")) {\n      set_path(\"dkala\");\n      fprintf(stderr,\"%s: path exists '%s', set\\n\",\n\t      procname, \".\/dkala\");\n      fflush(stderr);\n\n    } else if(exists_path(\".ressu\")) {\n      set_path(\".ressu\");\n      fprintf(stderr,\"%s: path exists '%s', set\\n\",\n\t      procname, \".ressu\");\n      fflush(stderr);\n\n    } else if(exists_path(\".\/\")) {\n      set_path(\".\/\");\n      fprintf(stderr,\"%s: path exists '%s', set\\n\",\n\t      procname, \".\/\");\n      fflush(stderr);\n\n    } else {\n      set_path(\".\/\");\n      fprintf(stderr,\"%s: path set '%s'\\n\",\n\t      procname, \".\/\");\n      fflush(stderr);\n\n    }\n\n    unsigned char command&#91;160], date&#91;16], filename&#91;64];\n    command_readline(\"date +%Y%m%d%H\", sizeof(date), date);\n    \/\/command_readline(\"date +%Y%m%d%H%M\", sizeof(date), date);\n    fprintf(stdout,\"readline date '%s'\\n\",date);\n    sprintf(filename,\"newressutest14.rnd.%s\",date);\n    if(!exists_path(filename)) {\n      sprintf(command,\".\/newressutest14.sh &gt;%s\",filename);\n      system(command);\n    }\n    \/\/fprintf(stderr,\" done.\\n\");\n    fflush(stderr);\n\n    set_path(savepath);\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Aloitin uuden ohjelman, jolla voi hakea terttu (tai sakki) muotoisesta tiedostosta haluamillaan avaimilla. T\u00e4t\u00e4 voi k\u00e4ytt\u00e4\u00e4 esimerkiksi palvelimen lokin valikoituun tulostukseen. <\/p>\n\n\n\n<p>Lis\u00e4tty uuteen terttuutil1 ohjelmaan p\u00e4tk\u00e4, joka parsii komentomerkkijonon, ja muodostaa siit\u00e4 terttu-yhteensopivan kyselyn: esimerkkej\u00e4 input kyselyst\u00e4 &#8216;a,b&#8217;, &#8216;a=1,b&#8217; &#8216;a,b,c&#8217; n\u00e4ist\u00e4 tehd\u00e4\u00e4n terttu muotoinen kysely &#8216;a&#8217;, &#8216;b&#8217; tai &#8216;a&#8217; = &#8220;1&#8221;, &#8216;b&#8217; tai &#8216;a&#8217;, &#8216;b&#8217;, &#8216;c&#8217; jne.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG59 2\n\nint db6_parsequery(int querylen, unsigned char *query, unsigned char *command)\n{\n  unsigned char *token, *p, *q;\n  int mode = 0, copymode = 0, count, valuetoo, exitcount = 0;\n  \n  p = command;\n  q = query;\n  mode = 20;\n  count = 0;\n  \n  while(*p != '\\0') {\n\n    unsigned char *prevp = NULL;\n    unsigned char *prevq = NULL;    \n    \n    prevp = p;\n    prevq = q;\n\n    if(count &lt; querylen)\n      *q = '\\0';\n\n    switch(mode) {\n\n    case 10:\n\n      token = \" \";\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\n      count += strlen(token);\n      mode = 20;\n      \n    case 20:\n\n      token = \"'\";\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\t\n      count += strlen(token);\n\n      copymode = 0; \/\/ 0 = isalpha, 1 = within quotes\n      db5_skipwhite(&amp;p);\n      if(*p == '\\'') { \/\/ skip possible first quote\n\tcopymode = 1;\n\tp++;\n\t\/\/db5_skipwhite(&amp;p);\n      }\n\n      token = \" \"; \/\/ placeholder for one character\n      while((copymode == 0 &amp;&amp; *p != ' ' &amp;&amp; *p != ',' &amp;&amp; *p != '=' &amp;&amp; *p != '\\0') ||\n\t    (copymode == 1 &amp;&amp; *p != '\\'' &amp;&amp; *p != '\\0')) {\n\tif(count + strlen(token) &lt; querylen) {\n\t  *q++ = *p;\n\t  *q = '\\0';\n\t}\n\tp++;\n\tcount++;\n      }\n\n      if(copymode) { \/\/ skip possible second quote\n\tif(*p == '\\'') {\n\t  p++;\n\t}\n\tdb5_skipwhite(&amp;p); \/\/ skip space after quote\n      }\n\n      token = \"'\"; \/\/ add single quote to set\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\n      count += strlen(token);\n\n      mode = 30;\n\n      break;\n\n    case 30:\n\n      valuetoo = 0;\n      \n      db5_skipwhite(&amp;p);\n      if(*p == '=') { \/\/ skip possible equals sign\n\tp++;\n\tdb5_skipwhite(&amp;p);\n\tvaluetoo = 1;\n      }\n\n      if(*p == '\"')\n\tvaluetoo = 1;\n      \n      if(isalpha(*p) || isdigit(*p) || *p == '_')\n\tvaluetoo = 1;\n      \n      if(valuetoo) {\n\ttoken = \" = \\\"\"; \/\/ add equals to set\n\tif(count + strlen(token) &lt; querylen) {\n\t  strcat (q, token);\n\t  q += strlen(q);\n\t}\n\tcount += strlen(token);\n\t\n\tcopymode = 0; \/\/ 0 = isalpha, 1 = within quotes\n\tdb5_skipwhite(&amp;p);\n\tif(*p == '\"') { \/\/ skip possible first quote\n\t  copymode = 1;\n\t  p++;\n\t  \/\/db5_skipwhite(&amp;p); \/\/ no skipwhite after first quote\n\t}\n\t\n\ttoken = \" \";\n\twhile((copymode == 0 &amp;&amp; *p != ' ' &amp;&amp; *p != ',' &amp;&amp; *p != '\\0') ||\n\t      (copymode == 1 &amp;&amp; *p != '\"' &amp;&amp; *p != '\\0')) {\n\t  if(count + strlen(token) &lt; querylen) {\n\t    *q++ = *p;\n\t    *q = '\\0';\n\t  }\n\t  p++;\n\t  count++;\n\t}\n\t\n\tif(copymode) { \/\/ skip possible second quote\n\t  \/\/db5_skipwhite(&amp;p); \/\/ no skipwhite before second quote\n\t  if(*p == '\\\"')\n\t    p++;\n\t  db5_skipwhite(&amp;p); \/\/ skip space after quote\n\t}\n\n\ttoken = \"\\\"\"; \/\/ add quote to set\n\tif(count + strlen(token) &lt; querylen) {\n\t  strcat (q, token);\n\t  q += strlen(q);\n\t}\n\tcount += strlen(token);\n      } \/\/ if(valuetoo\n      \n      mode = 40;\n      break;\n      \n    case 40:\n\n      db5_skipwhite(&amp;p);\n      if(*p == ',') {\n\tp++;\n\tdb5_skipwhite(&amp;p);\n      }\n\n      token = \",\"; \/\/ add comma to set\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(token);\n      }\n      count += strlen(token);\n\n      mode = 10;\n      break;\n\n    }\n\n#ifdef DEBUG59\n    fprintf(stderr,\"command:`%s`\", p);\n    fprintf(stderr,\", query:`%s`\", query);\n    fprintf(stderr,\", mode:%d\", mode);\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(*p == '\\0')\n      break;\n    if(prevp == p &amp;&amp; prevq == q) {\n      fprintf(stderr,\"%s: illegal character '\", procname);\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", mode:%d\", mode);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n      if(++ exitcount == 10) {\n\tbreak;\n      }\n    }\n  }\n\n  return(count);\n}\n<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty koodi, joka sivuttaa tulostetta sivuittain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;termios.h&gt;\n\nstruct termios old, new;\n\nvoid startprompt()\n{\n  setvbuf(stdout, NULL, _IONBF, 0);\n  tcgetattr(0, &amp;old);\n  new = old;\n  new.c_lflag &amp;= ~(ICANON | ECHO);\n  \/\/new.c_lflag &amp;= ~(ISIG | ICANON | ECHO);\n  new.c_cc&#91;VMIN] = 1;\n  new.c_cc&#91;VTIME] = 2;\n  tcsetattr(0, TCSANOW, &amp;new);\n}\n\nvoid endprompt()\n{\n  tcsetattr(0, TCSANOW, &amp;old);\n}\n\nvoid util_backspacechars(int chars)\n{\n  int c;\n  \n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\" \");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n}\n\nint screenlinesleft = 0, screenmaxchars, screenmaxlines;\nint screenchars = 0;\nint quitcmd = 0;\n\nvoid more_wait()\n{\n  int c;\n  unsigned char *moretext = \"---more---\";\n  \n  startprompt();\n  fprintf(stdout,\"%s\", moretext);\n\n  \/\/ wait until something below is pressed\n  \n  for(;;) {\n    c = getchar();\n    if(c == ' ') {\n      screenlinesleft = screenmaxlines; \/\/ full screen\n      break;\n    } else if(c == '\\n') {\n      screenlinesleft = 1; \/\/ one line\n      break;\n    } else if(c == 'q') { \/\/ quit\n      quitcmd = 1;\n      break;\n    }\n  }\n  \n  util_backspacechars(strlen(moretext));\n  \n  endprompt();\n}\n\n#include &lt;stdarg.h&gt;\n\nvoid more_printf(const char *format, ...)\n{\n  int count;\n  va_list args;\n  unsigned char *p;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args, format);\n  count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf=realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ prompt more for full screen pages.\n  \n  p=printbuf;\n  while(*p!='\\0') {\n    putchar(*p);\n    if(*p=='\\n' || ++screenchars==screenmaxchars) {\n      screenchars=0;\n      if(--screenlinesleft==0) {\n\tmore_wait();\n      }\n    }\n    p++;\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty koodi, jolla valitaan kysely\u00e4 vastaavat tietueet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db6_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG72\n  fprintf(stdout,\"match:%s\", match);\n  fprintf(stdout,\", set:%s\", set);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db5_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db5_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;m); \/\/ match\n    db5_skipwhite(&amp;m);\n\n#ifdef DEBUG72\n    fprintf(stdout,\"db6_get_element2: \");\n    fprintf(stdout,\"name2:%.*s(%d)\", namelen2, name2, namelen2);\n    fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif    \n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db5_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb5_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;s); \/\/ set\n      db5_skipwhite(&amp;s);\n\n#ifdef DEBUG72\n      fprintf(stdout,\"db6_get_element: \");\n      fprintf(stdout,\"name:%.*s(%d)\", namelen, name, namelen);\n      fprintf(stdout,\", value:%.*s(%d)\", valuelen, value, valuelen);\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      \n      if((name2 != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value2 == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n#ifdef DEBUG72\n  fprintf(stdout,\"db6_match done\");\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty koodi project, joka palauttaa rivist\u00e4 vain kyselyn sis\u00e4lt\u00e4m\u00e4t sarakkeet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db6_project(unsigned int *projectlen, unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  if(db5_set != NULL) {\n    free(db5_set);\n    db5_set = NULL;\n  }\n\n  q = query;\n  while(*q != '\\0') {\n    db5_skipwhite(&amp;q);\n    db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db5_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db5_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db5_skipwhite(&amp;s);\n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db5_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb5_skipwhite(&amp;s);\n      }\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\n\tunsigned char name3&#91;64];\n\tunsigned char value3&#91;128];\n\n\tmemset(name3,0,sizeof(name3));\n\tmemset(value3,0,sizeof(value3));\n\n\tstrncpy(name3, name2, namelen2);\n\tstrncpy(value3, value2, valuelen2);\n\n\tdb5_put(name3, value3);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n\n  if(db5_set != NULL) {\n    if(*projectlen &lt; strlen(db5_set) + 1) {\n      unsigned char *prevproject = *project;\n      *projectlen = strlen(db5_set) + 1;\n      *project = realloc(*project, *projectlen);\n      if(prevproject == NULL)\n\t**project = '\\0';\n    }\n    strcpy(*project, db5_set);\n  } else\n    *project = '\\0';\n}<\/code><\/pre>\n\n\n\n<p>Kirjoitettu rutiini, joka voi lukea tiedostosta merkkijonon, jonka pituutta ei tiedet\u00e4 etuk\u00e4teen. Ohjelma vain suurentaa muistipuskuria tarvittaessa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *util_fgets(int *commandlen, unsigned char **command, FILE *fp1)\n{\n  int count, retval;\n  unsigned char buffer&#91;64];\n  unsigned char *buf = *command;\n\n  count = 0;\n\n  if(buf != NULL)\n    buf&#91;0] = '\\0';\n\n  retval = 1;\n\n  for(;;) {\n    if(fgets(buffer, sizeof(buffer), fp1) == NULL) {\n      retval = 0;\n      break;\n    }\n\n    \/\/fprintf(stderr,\" %s\",buffer);\n    count = 0;\n    if(buf != NULL)\n      count += strlen(buf);\n    count += strlen(buffer);\n\n    if(*commandlen &lt; count) {\n      unsigned char *prevbuf = buf;\n      *commandlen = count;\n      buf = realloc(buf, *commandlen);\n      if(prevbuf == NULL)\n\tbuf&#91;0] = '\\0';\n    }\n    \n    strcat(buf, buffer);\n\n    if(buf&#91;strlen(buf)-1] == '\\n') {\n      buf&#91;strlen(buf)-1] = '\\0';\n      break;\n    }\n  }\n  *command = buf;\n\n  if(retval == 0)\n    return(NULL);\n  else\n    return(*command);\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraava p\u00e4tk\u00e4 tekee kyselyn, ja tulostaa vastauksen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int util_doquery(unsigned char *query, unsigned char *filename)\n{\n  FILE *fp1;\n  static unsigned char *line = NULL;\n  static unsigned int linelen = 0;\n  static unsigned char *project = NULL;\n  static unsigned int projectlen = 0;\n  \n  if((fp1 = fopen(filename,\"r\"))== NULL) {\n    fprintf(stderr,\"%s: cannot open file `%s`\\n\", procname, filename);\n    return(1);\n  }\n\n  db6_setheaderflags(\"project\", 0); \/\/ standard: sorted, no duplicates\n  db6_setheaderquery(\"project\", query);\n  db6_deletesets(\"project\");\n\n  while(util_fgets(&amp;linelen, &amp;line, fp1) != NULL) {\n    if(quitcmd)\n      break;\n    if(line&#91;strlen(line)-1] == '\\n')\n      line&#91;strlen(line)-1] = '\\0';\n    if(db6_match(line, query)) {\n      db6_project(&amp;projectlen, &amp;project, line, query);\n      db6_putset(\"project\", project);\n    }\n  }\n  fclose(fp1);\n\n  int c = 0;\n  for(;;) {\n    unsigned char *set;\n    if(quitcmd)\n      break;\n    set = db6_getset(\"project\", c);\n    if(set == NULL)\n      break;\n    more_printf(\"%d*`%s`\\n\", c, set);\n    c++;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty db6_putset koodi lajittelulle (ja tuplille):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db6_putset(unsigned char *setname, unsigned char *set)\n{\n  int add;\n  struct setheader *sh;\n\n  sh = db6_setheader(setname);\n\n  struct setline **ppsetline;\n\n  add = 1;\n  ppsetline = &amp;sh-&gt;first;\n  while(*ppsetline != NULL) { \/\/ duplicates\n    if((sh-&gt;flags &amp; DB6_DUP) == 0 &amp;&amp;\n       !strcmp(set, (*ppsetline)-&gt;set)) {\n      add = 0;\n      break;\n    }\n    if((sh-&gt;flags &amp; DB6_NOSORT) == 0 &amp;&amp; \/\/ sort\n       strcmp(set, (*ppsetline)-&gt;set) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppsetline = &amp;((*ppsetline)-&gt;next);\n  }\n\n  if(add) {\n    struct setline *nsl;\n    nsl = malloc(sizeof(struct setline));\n    nsl-&gt;set = db6_set(set);\n#ifdef DEBUG66\n    more_printf(\"Adding chain `%s`, set `%s`\\n\", setname, nsl-&gt;set);\n#endif\n    nsl-&gt;next = *ppsetline;\n    *ppsetline = nsl;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraava kappale on p\u00e4\u00e4ohjelmassa (main) oleva rutiini, jolla voidaan tehd\u00e4 testiaineistoa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define TEST_SETS 9\n#define TEST_ITEMS 3\n  \n  if(testflag) {\n    \/\/ 'a'='1', 'b'='1', 'c'='1'\n    \/\/ 'a'='2', 'b'='1', 'c'='1'\n    \/\/ 'a'='3', 'b'='2', 'c'='1'\n    \/\/ 'a'='4', 'b'='2', 'c'='2'\n    \/\/ 'a'='5', 'b'='3', 'c'='2'\n    \/\/ 'a'='6', 'b'='3', 'c'='2'\n    \/\/ 'a'='7', 'b'='4', 'c'='3'\n    \/\/ 'a'='8', 'b'='4', 'c'='3'\n    \/\/ 'a'='9', 'b'='5', 'c'='3'\n    for(c = 0; c &lt; TEST_SETS; c++) {\n      first = 1;\n      for(d = 0; d &lt; TEST_ITEMS ; d++) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tfprintf(stdout,\"'%c'\", 'a' + d);\n\tfprintf(stdout,\"=\");\n\tfprintf(stdout,\"'%d'\", c \/ (d + 1) + 1);\n\tfirst = 0;\n      }\n      fprintf(stdout,\"\\n\");\n    }\n  }\n<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini mahdollistaa lajittelun haussa. Lajittelu tehd\u00e4\u00e4n kenttien kyselyn j\u00e4rjestyksess\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db6_putset(unsigned char *setname, unsigned char *set)\n{\n  int add;\n  struct setheader *sh;\n\n  sh = db6_setheader(setname);\n\n  struct setline **ppsetline;\n\n  add = 1;\n  ppsetline = &amp;sh-&gt;first;\n  while(*ppsetline != NULL) { \/\/ duplicates\n    if((sh-&gt;flags &amp; DB6_DUP) == 0 &amp;&amp;\n       !strcmp(set, (*ppsetline)-&gt;set)) {\n      add = 0;\n      break;\n    }\n    if((sh-&gt;flags &amp; DB6_NOSORT) == 0 &amp;&amp; \/\/ sort\n       strcmp(set, (*ppsetline)-&gt;set) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppsetline = &amp;((*ppsetline)-&gt;next);\n  }\n\n  if(add) {\n    struct setline *thissetline;\n    thissetline = malloc(sizeof(struct setline));\n    thissetline-&gt;set = db6_set(set);\n    sh-&gt;count++;\n#ifdef DEBUG66\n    more_printf(\"Adding chain `%s`, set `%s`\\n\", setname, thissetline-&gt;set);\n#endif\n    thissetline-&gt;next = *ppsetline;\n    *ppsetline = thissetline;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini siirt\u00e4\u00e4 k\u00e4sitelt\u00e4v\u00e4n kyselyn tuloksen (setheader) aina listan alkuun: N\u00e4in usein k\u00e4ytett\u00e4v\u00e4t kyselyt l\u00f6ytyv\u00e4t nopeammin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static struct setheader *db6_setheader(unsigned char *setname)\n{\n  struct setheader **ppsetheader, *thissetheader;\n\n  ppsetheader = &amp;firstsetheader;\n  while(*ppsetheader != NULL) {\n    if(!strcmp(setname, (*ppsetheader)-&gt;setname))\n      break;\n    ppsetheader = &amp;((*ppsetheader)-&gt;next);\n  }\n\n  if(*ppsetheader == NULL) { \/\/ does not exist, create\n    thissetheader = malloc(sizeof(struct setheader));\n    thissetheader-&gt;setname = malloc(strlen(setname) + 1);\n    strcpy(thissetheader-&gt;setname, setname);\n    thissetheader-&gt;flags = 0;\n    thissetheader-&gt;query = NULL;\n    thissetheader-&gt;count = 0;\n    thissetheader-&gt;first = NULL;\n    \/\/ put to first\n    thissetheader-&gt;next = firstsetheader;\n    firstsetheader = thissetheader;\n#ifdef DEBUG66\n    fprintf(stdout,\"added set `%s` as first set\\n\",setname);\n#endif\n  } else {\n    \/\/ remove from list\n    thissetheader = *ppsetheader;\n    *ppsetheader = thissetheader-&gt;next;\n    \/\/ add back to 1st of list\n    thissetheader-&gt;next = firstsetheader;\n    firstsetheader = thissetheader;\n#ifdef DEBUG66\n    fprintf(stdout,\"added set `%s` as first set\\n\",setname);\n#endif\n  }\n  return(thissetheader);\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini poistaa kyselyn set:in. Samalla lasketaan viittauslaskuria (count), ja jos set:iin ei ole en\u00e4\u00e4 viittauksia, se poistetaan muistista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db6_deleteset(unsigned char *set)\n{\n  int found;\n  struct set **ppset;\n\n  found = 0;\n  ppset = &amp;firstset;\n  while(*ppset != NULL) {\n    if(!strcmp((*ppset)-&gt;set, set)) {\n      found = 1;\n      break;\n    }\n    ppset = &amp;((*ppset)-&gt;next);\n  }\n  \n  if(found) {\n    \/\/ set found\n    \/\/ decrement reference counter\n    (*ppset)-&gt;count--;\n    \/\/ if no references delete set\n    if((*ppset)-&gt;count == 0) { \n      struct set *prevppset;\n      prevppset = *ppset;\n#ifdef DEBUG66\n      more_printf(\"Set `%s` deleted\\n\", (*ppset)-&gt;set);\n#endif\n      (*ppset) = (*ppset)-&gt;next;\n      free(prevppset-&gt;set);\n      free(prevppset);\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa on ohjelma kokonaisuudessaan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n\n#include \"sha256.h\"\n\nunsigned char *procname = NULL;\nstatic unsigned char *programname = \"Terttuutil1 version 0.17 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2023 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nint newressu_output = 0;\n\nvoid ressu_dump(unsigned char *header, int len, unsigned char *buf, int linelen)\n{\n  int c;\n\n  if(newressu_output) {\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  for(c = 0; c &lt; len; c++) {\n    if(c % linelen == 0) {\n      if(c &gt; 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%-10s\", header);\n    }\n    fprintf(stdout,\" %02x\", buf&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n}\n\nvoid dumpbin(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    if(isprint(buf&#91;c]) &amp;&amp; buf&#91;c]!= ' ')\n      fputc(buf&#91;c], stderr);\n    else\n      fprintf(stderr,\"\\\\%02x\", buf&#91;c]);\n}\n\nunsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n\n#ifdef DEBUG20\n  ressu_dump(\"cvar\", cvarsize + 1, cvar, 32);\n#endif\n}\n\n#define aCVARRANDOMSTART 2 \/\/ off by default\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n  \n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n#ifdef CVARRANDOMSTART\n  ressu_genbytes(8, (unsigned char *)&amp;cvar);  \n#endif\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}\n\n#define GENT_SIZE 1024\n\nstatic unsigned char gent&#91;GENT_SIZE]; \/\/ orig 1024 \nstatic unsigned int gent_pos = 0;\n\nstatic unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n}\n\nstatic int streamt_pos = 0;\n\nvoid stream_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n      stream_internalbytes(streamt); \/\/ read next random bytes\n\n      stream_internalbytes(stream_key); \/\/ change key\n\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n\n  } \/\/ end of for(c = 0; c &lt; size; c++)\n}\n\n#define STREAM_KEY_ROUNDS 1024 \/\/ should be fast enough and slow enough, now 1024\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n\n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n    HashFinal(stream_key, &amp;hash);\n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#define DEBUG21 2\n\n#ifdef DEBUG21\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" randomness from key, key=\");\n  dumpbin(stderr, size, key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n  \n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n}\n\nvoid gent_clear()\n{\n  memset(gent, 0, sizeof(gent));\n}\n\nint stream_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n#ifdef DEBUG23\n    ressu_dump(\"oldgent\", 32, gent, 32); \/\/ first 32 bytes\n#endif\n    gent_clear();\n    stream_bytes(sizeof(gent), gent);\n#ifdef DEBUG23\n    ressu_dump(\"newgent\", 32, gent, 32); \/\/ first 32 bytes\n#endif \n } \/\/ if(gent_pos==0\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n#ifdef DEBUG18\n  fprintf(stdout, \"{%02x}\", ch);\n#endif\n  return(ch);\n}\n\nunsigned long stream_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) { \/\/ one byte\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n\n    } else if(limit &lt;= 0x10000) { \/\/ two bytes\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n\n    } else if(limit &lt;= 0x1000000) { \/\/ three bytes\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n\n    } else if(limit &lt;= 0x100000000) { \/\/ four bytes\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n\n    } else if(limit &lt;= 0x10000000000) { \/\/ five bytes\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n\n    } else if(limit &lt;= 0x1000000000000) { \/\/ six bytes\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n\n    } else if(limit &lt;= 0x100000000000000) { \/\/ seven bytes\n      highlimit = (0x100000000000000 \/ limit) * limit;      \n      bytes = 7;\n\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | stream_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n  return(word);\n}\n\n#include &lt;termios.h&gt;\n\nstruct termios old, new;\n\nvoid startprompt()\n{\n  setvbuf(stdout, NULL, _IONBF, 0);\n  tcgetattr(0, &amp;old);\n  new = old;\n  new.c_lflag &amp;= ~(ICANON | ECHO);\n  \/\/new.c_lflag &amp;= ~(ISIG | ICANON | ECHO);\n  new.c_cc&#91;VMIN] = 1;\n  new.c_cc&#91;VTIME] = 2;\n  tcsetattr(0, TCSANOW, &amp;new);\n}\n\nvoid endprompt()\n{\n  tcsetattr(0, TCSANOW, &amp;old);\n}\n\nvoid util_backspacechars(int chars)\n{\n  int c;\n  \n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\" \");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n}\n\nint screenlinesleft = 0, screenmaxchars, screenmaxlines;\nint screenchars = 0;\nint quitcmd = 0;\n\n#include &lt;sys\/ioctl.h&gt; \/\/ for TIOCGWINSZ\n\nint more = 1;\n\nvoid more_init()\n{\n  struct winsize w;\n  ioctl(0, TIOCGWINSZ, &amp;w);\n  screenmaxchars = w.ws_col;\n  screenmaxlines = w.ws_row-1;\n  screenlinesleft = screenmaxlines;\n  \n  quitcmd = 0;\n}\n\nvoid more_wait()\n{\n  int c;\n  unsigned char *moretext = \"---more---\";\n  \n  startprompt();\n  fprintf(stderr,\"%s\", moretext);\n\n  \/\/ wait until something below is pressed\n  \n  for(;;) {\n    c = getchar();\n    if(c == ' ') {\n      screenlinesleft = screenmaxlines; \/\/ full screen\n      break;\n    } else if(c == '\\n') {\n      screenlinesleft = 1; \/\/ one line\n      break;\n    } else if(c == 'q') { \/\/ quit\n      quitcmd = 1;\n      break;\n    }\n  }\n  \n  util_backspacechars(strlen(moretext));\n  \n  endprompt();\n}\n\n#include &lt;stdarg.h&gt;\n\nvoid more_printf(FILE *fp1, const char *format, ...)\n{\n  int count;\n  va_list args;\n  unsigned char *p;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args, format);\n  count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf=realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ prompt more for full screen pages.\n  \n  p=printbuf;\n  while(*p!='\\0') {\n    fputc(*p, fp1);\n    if(*p=='\\n' || ++screenchars==screenmaxchars) {\n      screenchars=0;\n      if(more &amp;&amp; --screenlinesleft==0) {\n\tmore_wait();\n      }\n    }\n    p++;\n  }\n}\n\nunsigned char *db5_set = NULL;\n\nunsigned char *db5_get_set()\n{\n  return(db5_set);\n}\n\nvoid db5_skipwhite(unsigned char **p)\n{\n  while(isblank(**p))\n    (*p)++;\n}\n\n#define aDEBUG8 2\n#define aDEBUG9 2\n#define aDEBUG10 2\n#define aDEBUG11 2\n\nvoid db5_get_element(unsigned int *namelen, unsigned char **name, unsigned int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db5_skipwhite(&amp;p);\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *name = p;\n    *namelen = 0;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  } else\n    *name = NULL;\n\n  db5_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db5_skipwhite(&amp;p);\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *value = p;\n    *valuelen = 0;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  } else\n    *value = NULL;\n\n  db5_skipwhite(&amp;p);\n\n#ifdef DEBUG8\n  fprintf(stdout,\"db5_get_element():\");\n  fprintf(stdout,\" name:%.*s(%d)\", *namelen, *name, *namelen);\n  fprintf(stdout,\", value:%.*s(%d)\", *valuelen, *value, *valuelen);\n  fprintf(stdout,\", next:%s\",p);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n  *p2 = p;\n}\n\nint db5_get(unsigned char *name, int valuesize, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen = strlen(name);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** get\\n\");\n#endif\n  \n  value&#91;0] = '\\0';\n\n  if(db5_set != NULL) {\n\n    firstelement = 1;\n    p = db5_set;\n\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n      \n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n#ifdef DEBUG9\n      fprintf(stdout,\"get name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      db5_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(db5_set != NULL)\n  return(retval);\n}\n\n#define aSORTED 2\n\nvoid db5_put(unsigned char *name, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  unsigned int namelen = strlen(name);\n  unsigned int valuelen = strlen(value);\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG9\n  fprintf(stdout,\"********** put\\n\");\n#endif\n  \n  firstelement = 1;\n  lastelement = 0;\n\n  if(db5_set != NULL) {\n\n    p = db5_set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db5_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb5_skipwhite(&amp;p);\n      }\n\n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db5_skipwhite(&amp;p);\n      \n#ifdef DEBUG9\n      fprintf(stdout,\"put name:%s\", name);\n      fprintf(stdout,\", name2:%.*s(%d)\", namelen2, name2, namelen2);\n      fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n      fprintf(stdout,\"\\n\");\n#endif\n\n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } else { \/\/ else of if(db5_set != NULL)\n\n    lastelement = 1;\n    firstelement = 1;\n\n  } \/\/ end of if(db5_set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n\n  if((firstelement &amp;&amp; found) || \/\/ first and existing\n     (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n    elementfmt = \"'%s' = \\\"%s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n  else if(firstelement) \/\/ first and not existing element\n    elementfmt = \"'%s' = \\\"%s\\\", \"; \/\/ --&gt; comma in the end (first new)\n  else\n    elementfmt = \", '%s' = \\\"%s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n\n  \/\/ print element\n\n  count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  if(elementsize &lt; count) {\n    elementsize = count;\n    if((element = realloc(element, elementsize)) == NULL) {\n      fprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n    count = snprintf(element, elementsize, elementfmt, name, value) + 1;\n  }\n\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(db5_set != NULL) {\n    count += strlen(db5_set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout, \"old length:%ld %s\\n\", oldcount, db5_set);\n    fflush(stdout);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempdb5_set = db5_set;\n    if((db5_set = realloc(db5_set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = db5_set + (thiselement - tempdb5_set);\n    if(nextelement != NULL)\n      nextelement = db5_set + (nextelement - tempdb5_set);\n\n    if(tempdb5_set == NULL)\n      db5_set&#91;0] = '\\0';\n  }\n\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = db5_set + strlen(db5_set);\n  if(nextelement == NULL)\n    nextelement = db5_set + strlen(db5_set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stdout,\"new length:%ld %s\\n\", count, db5_set);\n    fflush(stdout);\n  }\n#endif  \n  \n#ifdef DEBUG10\n  fprintf(stdout,\", set      %s(%ld)\", db5_set, strlen(db5_set));\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}\n\n#define aDEBUG72 2\n\nint db6_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG72\n  fprintf(stdout,\"match:%s\", match);\n  fprintf(stdout,\", set:%s\", set);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db5_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db5_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;m); \/\/ match\n    db5_skipwhite(&amp;m);\n\n#ifdef DEBUG72\n    fprintf(stdout,\"db6_get_element2: \");\n    fprintf(stdout,\"name2:%.*s(%d)\", namelen2, name2, namelen2);\n    fprintf(stdout,\", value2:%.*s(%d)\", valuelen2, value2, valuelen2);\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif    \n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db5_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb5_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;s); \/\/ set\n      db5_skipwhite(&amp;s);\n\n#ifdef DEBUG72\n      fprintf(stdout,\"db6_get_element: \");\n      fprintf(stdout,\"name:%.*s(%d)\", namelen, name, namelen);\n      fprintf(stdout,\", value:%.*s(%d)\", valuelen, value, valuelen);\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      \n      if((name2 != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value2 == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n#ifdef DEBUG72\n  fprintf(stdout,\"db6_match done\");\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  return(ok);\n}\n\n#define aDEBUG50 2\n#define aDEBUG51 2\n\nvoid db6_project(unsigned int *projectlen, unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  if(db5_set != NULL) {\n    free(db5_set);\n    db5_set = NULL;\n  }\n\n  q = query;\n  while(*q != '\\0') {\n    db5_skipwhite(&amp;q);\n    db5_get_element(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db5_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db5_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db5_skipwhite(&amp;s);\n      db5_get_element(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db5_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb5_skipwhite(&amp;s);\n      }\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\n\tunsigned char name3&#91;64];\n\tunsigned char value3&#91;128];\n\n\tmemset(name3,0,sizeof(name3));\n\tmemset(value3,0,sizeof(value3));\n\n\tstrncpy(name3, name2, namelen2);\n\tstrncpy(value3, value2, valuelen2);\n\n\tdb5_put(name3, value3);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n\n  if(db5_set != NULL) {\n    if(*projectlen &lt; strlen(db5_set) + 1) {\n      unsigned char *prevproject = *project;\n      *projectlen = strlen(db5_set) + 1;\n      *project = realloc(*project, *projectlen);\n      if(prevproject == NULL)\n\t**project = '\\0';\n    }\n    strcpy(*project, db5_set);\n  } else\n    *project = '\\0';\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\n#define aDEBUG59 2\n\nint db6_parsequery(int querylen, unsigned char *query, unsigned char *command)\n{\n  unsigned char *token, *p, *q;\n  int mode = 0, copymode = 0, count, valuetoo, exitcount = 0;\n  \n  p = command;\n  q = query;\n  mode = 20;\n  count = 0;\n  \n  while(*p != '\\0') {\n\n    unsigned char *prevp = NULL;\n    unsigned char *prevq = NULL;    \n    \n    prevp = p;\n    prevq = q;\n\n    if(count &lt; querylen)\n      *q = '\\0';\n\n    switch(mode) {\n\n    case 10:\n\n      token = \" \";\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\n      count += strlen(token);\n      mode = 20;\n      \n    case 20:\n\n      token = \"'\";\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\t\n      count += strlen(token);\n\n      copymode = 0; \/\/ 0 = isalpha, 1 = within quotes\n      db5_skipwhite(&amp;p);\n      if(*p == '\\'') { \/\/ skip possible first quote\n\tcopymode = 1;\n\tp++;\n\t\/\/db5_skipwhite(&amp;p);\n      }\n\n      token = \" \"; \/\/ placeholder for one character\n      while((copymode == 0 &amp;&amp; *p != ' ' &amp;&amp; *p != ',' &amp;&amp; *p != '=' &amp;&amp; *p != '\\0') ||\n\t    (copymode == 1 &amp;&amp; *p != '\\'' &amp;&amp; *p != '\\0')) {\n\tif(count + strlen(token) &lt; querylen) {\n\t  *q++ = *p;\n\t  *q = '\\0';\n\t}\n\tp++;\n\tcount++;\n      }\n\n      if(copymode) { \/\/ skip possible second quote\n\tif(*p == '\\'') {\n\t  p++;\n\t}\n\tdb5_skipwhite(&amp;p); \/\/ skip space after quote\n      }\n\n      token = \"'\"; \/\/ add single quote to set\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(q);\n      }\n      count += strlen(token);\n\n      if(*p == ',') \/\/ no value\n\tmode = 40; \/\/ skip to comma\n      else\n\tmode = 30; \/\/ go thru value\n      break;\n\n    case 30:\n\n      valuetoo = 0;\n      \n      db5_skipwhite(&amp;p);\n      if(*p == '=') { \/\/ skip possible equals sign\n\tp++;\n\tdb5_skipwhite(&amp;p);\n\tvaluetoo = 1;\n      }\n\n      if(*p == '\"')\n\tvaluetoo = 1;\n      \n      if(isalpha(*p) || isdigit(*p) || *p == '_')\n\tvaluetoo = 1;\n      \n      if(valuetoo) {\n\ttoken = \" = \\\"\"; \/\/ add equals to set\n\tif(count + strlen(token) &lt; querylen) {\n\t  strcat (q, token);\n\t  q += strlen(q);\n\t}\n\tcount += strlen(token);\n\t\n\tcopymode = 0; \/\/ 0 = isalpha, 1 = within quotes\n\tdb5_skipwhite(&amp;p);\n\tif(*p == '\"') { \/\/ skip possible first quote\n\t  copymode = 1;\n\t  p++;\n\t  \/\/db5_skipwhite(&amp;p); \/\/ no skipwhite after first quote\n\t}\n\t\n\ttoken = \" \";\n\twhile((copymode == 0 &amp;&amp; *p != ' ' &amp;&amp; *p != ',' &amp;&amp; *p != '\\0') ||\n\t      (copymode == 1 &amp;&amp; *p != '\"' &amp;&amp; *p != '\\0')) {\n\t  if(count + strlen(token) &lt; querylen) {\n\t    *q++ = *p;\n\t    *q = '\\0';\n\t  }\n\t  p++;\n\t  count++;\n\t}\n\t\n\tif(copymode) { \/\/ skip possible second quote\n\t  \/\/db5_skipwhite(&amp;p); \/\/ no skipwhite before second quote\n\t  if(*p == '\\\"')\n\t    p++;\n\t  db5_skipwhite(&amp;p); \/\/ skip space after quote\n\t}\n\n\ttoken = \"\\\"\"; \/\/ add quote to set\n\tif(count + strlen(token) &lt; querylen) {\n\t  strcat (q, token);\n\t  q += strlen(q);\n\t}\n\tcount += strlen(token);\n      } \/\/ if(valuetoo\n      \n      mode = 40;\n      break;\n      \n    case 40:\n\n      db5_skipwhite(&amp;p);\n      if(*p == ',') {\n\tp++;\n\tdb5_skipwhite(&amp;p);\n      }\n\n      token = \",\"; \/\/ add comma to set\n      if(count + strlen(token) &lt; querylen) {\n\tstrcat (q, token);\n\tq += strlen(token);\n      }\n      count += strlen(token);\n\n      mode = 10;\n      break;\n\n    }\n\n#ifdef DEBUG59\n    fprintf(stderr,\"command:`%s`\", p);\n    fprintf(stderr,\", query:`%s`\", query);\n    fprintf(stderr,\", mode:%d\", mode);\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(*p == '\\0')\n      break;\n    if(prevp == p &amp;&amp; prevq == q) {\n      fprintf(stderr,\"%s: illegal character '\", procname);\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", mode:%d\", mode);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n      if(++ exitcount == 10) {\n\tbreak;\n      }\n    }\n  }\n\n  return(count);\n}\n\n#define aDEBUG66 2\n\n#define DB6_NOSORT 1\n#define DB6_DUP 2\n\nstruct setheader {\n  unsigned char *setname;\n  int flags;\n  unsigned char *query;\n  int count;\n  struct setheader *next;\n  struct setline *first;\n};\n\nstruct setheader *firstsetheader = NULL;\n\nstruct setline {\n  unsigned char *set;\n  struct setline *next;\n};\n\nstruct set {\n  unsigned char *set;\n  int count;\n  struct set *next;\n};\n\nstruct set *firstset = NULL;\n\nstatic struct setheader *db6_setheader(unsigned char *setname)\n{\n  struct setheader **ppsetheader, *thissetheader;\n\n  ppsetheader = &amp;firstsetheader;\n  while(*ppsetheader != NULL) {\n    if(!strcmp(setname, (*ppsetheader)-&gt;setname))\n      break;\n    ppsetheader = &amp;((*ppsetheader)-&gt;next);\n  }\n\n  if(*ppsetheader == firstsetheader) {\n#ifdef DEBUG66\n    more_printf(stderr, \"set `%s` is allready the first set\\n\",setname);\n#endif\n  }\n  if(*ppsetheader == NULL) { \/\/ does not exist, create\n    thissetheader = malloc(sizeof(struct setheader));\n    thissetheader-&gt;setname = malloc(strlen(setname) + 1);\n    strcpy(thissetheader-&gt;setname, setname);\n    thissetheader-&gt;flags = 0;\n    thissetheader-&gt;query = NULL;\n    thissetheader-&gt;count = 0;\n    thissetheader-&gt;first = NULL;\n    \/\/ put to first\n    thissetheader-&gt;next = firstsetheader;\n    firstsetheader = thissetheader;\n#ifdef DEBUG66\n    more_printf(stderr, \"added set `%s` as first set\\n\",setname);\n#endif\n  } else {\n    \/\/ remove from list\n    thissetheader = *ppsetheader;\n    *ppsetheader = thissetheader-&gt;next;\n    \/\/ add back to 1st of list\n    thissetheader-&gt;next = firstsetheader;\n    firstsetheader = thissetheader;\n#ifdef DEBUG66\n    more_printf(stderr, \"added set `%s` as first set\\n\",setname);\n#endif\n  }\n  return(thissetheader);\n}\n\nstatic struct setheader *db6_setheaderflags(unsigned char *setname, int flags)\n{\n  struct setheader *sh;\n\n  sh = db6_setheader(setname);\n\n  sh-&gt;flags = flags;\n}\n\nstatic struct setheader *db6_setheaderquery(unsigned char *setname, unsigned char *query)\n{\n  struct setheader *sh;\n\n  sh = db6_setheader(setname);\n\n  if(sh-&gt;query != NULL)\n    free(sh-&gt;query);\n\n  sh-&gt;query = malloc(strlen(query) + 1);\n  strcpy(sh-&gt;query, query);\n}\n\nvoid db6_dumpsetheader(struct setheader *thissetheader)\n{\n  more_printf(stderr, \"setheader\");\n  more_printf(stderr, \" %p\", thissetheader);\n  more_printf(stderr, \" setname:`%s`\", thissetheader-&gt;setname);\n  more_printf(stderr, \", flags:%02x\", thissetheader-&gt;flags);\n  more_printf(stderr, \", query:`%s`\", thissetheader-&gt;query);\n  more_printf(stderr, \", count:%d\", thissetheader-&gt;count);\n  more_printf(stderr, \", next:%p\", thissetheader-&gt;next);\n  more_printf(stderr, \", first:%p\", thissetheader-&gt;first);\n  more_printf(stderr, \"\\n\");\n}\n\nvoid db6_dumpsetheaders()\n{\n  struct setheader *sh;\n  sh = firstsetheader;\n  while(sh != NULL) {\n    db6_dumpsetheader(sh);\n    sh=sh-&gt;next;\n  }\n}\n\nvoid db6_dumpsetline(struct setline *thissetline)\n{\n  more_printf(stderr, \"set\");\n  more_printf(stderr, \" %p\", thissetline);\n  more_printf(stderr, \" set:%s\", thissetline-&gt;set);\n  more_printf(stderr, \", next:%p\", thissetline-&gt;next);\n  more_printf(stderr, \"\\n\");\n}\n\nunsigned char *db6_set(unsigned char *set)\n{\n  int found;\n  struct set *s;\n\n  found = 0;\n  s = firstset;\n  while(s != NULL) {\n    if(!strcmp(s-&gt;set, set)) {\n      found = 1;\n      break;\n    }\n    s = s-&gt;next;\n  }\n  if(!found) {\n    struct set *thisset;\n    thisset = malloc(sizeof(struct set));\n    thisset-&gt;set = malloc(strlen(set) + 1);\n    strcpy(thisset-&gt;set, set);\n    thisset-&gt;count = 1;\n    \/\/more_printf(stdout, \"2:`%s`\", set);\n    thisset-&gt;next = firstset;\n    firstset = thisset;\n    s = thisset;\n  } else {\n    s-&gt;count++;\n  }\n  return(s-&gt;set);\n}\n\nvoid db6_putset(unsigned char *setname, unsigned char *set)\n{\n  int add;\n  struct setheader *sh;\n\n  sh = db6_setheader(setname);\n\n  struct setline **ppsetline;\n\n  add = 1;\n  ppsetline = &amp;sh-&gt;first;\n  while(*ppsetline != NULL) { \/\/ duplicates\n    if((sh-&gt;flags &amp; DB6_DUP) == 0 &amp;&amp;\n       !strcmp(set, (*ppsetline)-&gt;set)) {\n      add = 0;\n      break;\n    }\n    if((sh-&gt;flags &amp; DB6_NOSORT) == 0 &amp;&amp; \/\/ sort\n       strcmp(set, (*ppsetline)-&gt;set) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppsetline = &amp;((*ppsetline)-&gt;next);\n  }\n\n  if(add) {\n    struct setline *thissetline;\n    thissetline = malloc(sizeof(struct setline));\n    thissetline-&gt;set = db6_set(set);\n    sh-&gt;count++;\n#ifdef DEBUG66\n    more_printf(stderr, \"Adding chain `%s`, set `%s`\\n\", setname, thissetline-&gt;set);\n#endif\n    thissetline-&gt;next = *ppsetline;\n    *ppsetline = thissetline;\n  }\n}\n\nvoid db6_dumpset(struct set *thisset)\n{\n  more_printf(stderr, \"set\");\n  more_printf(stderr, \" %p\", thisset);\n  more_printf(stderr, \" set:`%s`\", thisset-&gt;set);\n  more_printf(stderr, \" count:%d\", thisset-&gt;count);\n  more_printf(stderr, \", next:%p\", thisset-&gt;next);\n  more_printf(stderr, \"\\n\");\n}\n\nvoid db6_dumpsets()\n{\n  struct set *s;\n  s = firstset;\n  while(s != NULL) {\n    db6_dumpset(s);\n    s = s-&gt;next;\n  }\n}\n\n\nvoid db6_deleteset(unsigned char *set)\n{\n  int found;\n  struct set **ppset;\n\n  found = 0;\n  ppset = &amp;firstset;\n  while(*ppset != NULL) {\n    if(!strcmp((*ppset)-&gt;set, set)) {\n      found = 1;\n      break;\n    }\n    ppset = &amp;((*ppset)-&gt;next);\n  }\n  \n  if(found) {\n    \/\/ set found\n    \/\/ decrement reference counter\n    (*ppset)-&gt;count--;\n    \/\/ if no references delete set\n    if((*ppset)-&gt;count == 0) { \n      struct set *prevppset;\n      prevppset = *ppset;\n#ifdef DEBUG66\n      more_printf(stderr, \"Set `%s` deleted\\n\", (*ppset)-&gt;set);\n#endif\n      (*ppset) = (*ppset)-&gt;next;\n      free(prevppset-&gt;set);\n      free(prevppset);\n    }\n  }\n}\n\n\n#ifdef OLD1\n\nvoid db6_deleteset(unsigned char *set)\n{\n  int found;\n  struct set *s;\n\n  found = 0;\n  s = firstset;\n  while(s != NULL) {\n    if(!strcmp(s-&gt;set, set)) {\n      found = 1;\n      break;\n    }\n    s = s-&gt;next;\n  }\n  if(found) {\n    s-&gt;count--;\n  }\n}\n\n#endif\n\nvoid db6_deletesets(unsigned char *setname)\n{\n  int c, found;\n  struct setheader *sh;\n  struct setline *sl, *sl2;\n  \n  sh = db6_setheader(setname);\n\n#ifdef DEBUG66\n  more_printf(stderr, \"Deleting chain `%s`\\n\",setname);\n#endif\n  sl = sh-&gt;first;\n  while(sl != NULL) {\n#ifdef DEBUG66\n    more_printf(stderr, \"Deleting:%s\\n\", sl-&gt;set);\n#endif\n    db6_deleteset(sl-&gt;set);\n    sh-&gt;count--;\n    sl2 = sl;\n    sl = sl2-&gt;next;\n    free(sl2);\n  }\n#ifdef DEBUG66\n  more_printf(stderr, \"Chain `%s` deleted\\n\",setname);\n#endif\n  sh-&gt;first = NULL;\n}\n\nunsigned char *db6_getset(unsigned char *setname, int lineno)\n{\n  int c;\n  struct setheader *sh;\n  \n  sh = db6_setheader(setname);\n  \/\/db6_dumpsetheader(sh);\n\n  struct setline *sl;\n  \n  sl = sh-&gt;first;\n  while(sl != NULL &amp;&amp; lineno &gt; 0) {\n    \/\/db6_dumpsetline(sl);\n    sl = sl-&gt;next;\n    lineno--;\n  }\n  if(sl == NULL)\n    return(NULL);\n  else {\n#ifdef DEBUG66\n    more_printf(stderr, \"Restoring chain `%s`, set `%s`\\n\", setname, sl-&gt;set);\n#endif\n    return(sl-&gt;set);\n  }\n}\n\nvoid util_parsequery(int *querylen, unsigned char **query, unsigned char *command)\n{\n  int count;\n  \n  count = db6_parsequery(*querylen, *query, command) + 1;\n  if(*querylen &lt; count) {\n    *querylen = count;\n    *query = realloc(*query, *querylen);\n    count = db6_parsequery(*querylen, *query, command) + 1;\n  }\n  more_printf(stderr, \"command:`%s`\", command);\n  more_printf(stderr, \", query:`%s`\", *query);\n  more_printf(stderr, \"\\n\");\n}\n\n#define aDEBUG83 2\n\nunsigned char *util_fgets(int *commandlen, unsigned char **command, FILE *fp1)\n{\n  int count, retval;\n  unsigned char buffer&#91;4];\n  unsigned char *buf = *command;\n\n  count = 0;\n\n  if(buf != NULL)\n    buf&#91;0] = '\\0';\n\n  retval = 1;\n\n  for(;;) {\n    if(fgets(buffer, sizeof(buffer), fp1) == NULL) {\n      retval = 0;\n      break;\n    }\n\n#ifdef DEBUG83\n\n    more_printf(stderr, \"\/`%s`\",buffer);\n\n#endif\n    \n    count = 0;\n    if(buf != NULL)\n      count += strlen(buf);\n    count += strlen(buffer) + 1;\n    \n    if(*commandlen &lt; count) {\n      unsigned char *prevbuf = buf;\n      *commandlen = count;\n      buf = realloc(buf, *commandlen);\n      if(prevbuf == NULL)\n\tbuf&#91;0] = '\\0';\n    }\n    \n    strcat(buf, buffer);\n\n    if(buf&#91;strlen(buf)-1] == '\\n') {\n      buf&#91;strlen(buf)-1] = '\\0';\n      break;\n    }\n  }\n  *command = buf;\n\n#ifdef DEBUG83\n\n  more_printf(stderr, \"\\n\");\n\n#endif\n    \n  \n#ifdef DEBUG83\n\n  more_printf(stderr, \"`%s`(%d)\", buf, strlen(buf));\n\n#endif\n  \n  if(retval == 0)\n    return(NULL);\n  else\n    return(*command);\n}\n\nint util_doquery(unsigned char *query, unsigned char *filename)\n{\n  FILE *fp1;\n  static unsigned char *line = NULL;\n  static unsigned int linelen = 0;\n  static unsigned char *project = NULL;\n  static unsigned int projectlen = 0;\n  \n  if((fp1 = fopen(filename,\"r\"))== NULL) {\n    fprintf(stderr,\"%s: cannot open file `%s`\\n\", procname, filename);\n    return(1);\n  }\n\n  \/\/db6_setheaderflags(\"project\", DB6_NOSORT | DB6_DUP);\n  \/\/db6_setheaderflags(\"project\", DB6_NOSORT);\n  \/\/db6_setheaderflags(\"project\", DB6_DUP);\n  db6_setheaderflags(\"project\", 0);\n  \/\/db6_setheaderflags(\"project\", DB6_NOSORT | DB6_DUP);\n  db6_setheaderquery(\"project\", query);\n  db6_deletesets(\"project\");\n\n  while(util_fgets(&amp;linelen, &amp;line, fp1) != NULL) {\n    if(quitcmd)\n      break;\n    if(line&#91;strlen(line)-1] == '\\n')\n      line&#91;strlen(line)-1] = '\\0';\n    if(db6_match(line, query)) {\n      db6_project(&amp;projectlen, &amp;project, line, query);\n      db6_putset(\"project\", project);\n    }\n  }\n  fclose(fp1);\n\n  int c = 0;\n  for(;;) {\n    unsigned char *set;\n    if(quitcmd)\n      break;\n    set = db6_getset(\"project\", c);\n    if(set == NULL)\n      break;\n    more_printf(stdout, \"%d*`%s`\\n\", c, set);\n    c++;\n  }\n}\n\nvoid terttuutilversion()\n{\n  fprintf(stdout,\"%s\\n\", programname);\n  fprintf(stdout,\"%s\\n\", copyright);\n  fflush(stdout);\n}\n\n#define aDEBUG96 2\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, first, printcomma = 0, queryflag = 0, testflag = 0, test2flag = 0;\n  unsigned char command&#91;4096], *p;\n  int commandlen = 4096;\n#define aDEBUG98 2\n\n  more = 0;\n  if(isatty(STDOUT_FILENO))\n    more = 1;\n  \n#ifdef DEBUG98\n  db5_set = \"'a' = \\\"1\\\", 'b' = \\\"2\\\", 'c' = \\\"3\\\"\";\n  db6_match(db5_set, \"'a' = \\\"1\\\"\");\n  db6_match(db5_set, \"'b' = \\\"2\\\"\");\n  db6_match(db5_set, \"'c' = \\\"3\\\"\");\n  db6_match(db5_set, \"'a'\");\n  db6_match(db5_set, \"'b'\");\n  db6_match(db5_set, \"'c'\");\n  db6_match(db5_set, \"'a' = \\\"a\\\"\");\n  db6_match(db5_set, \"'b' = \\\"b\\\"\");\n  db6_match(db5_set, \"'c' = \\\"c\\\"\");\n#endif\n\n  procname = argv&#91;0];\n  \n  first = 1;\n  command&#91;0] = '\\0';\n\n  int help = 0, stat = 1;\n  unsigned char filename&#91;128] = \"terttuutil1.3.skk\";;\n  \n  \/\/\n  \/\/ look thru command line parameters\n  \/\/\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(!strncmp(\"-\", argv&#91;c], 1)) {\n\n      if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c])) {\n\thelp = 1;\n\t\n      } else if(!strncmp(\"--filename\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  strncpy(filename, argv&#91;c] + 10, sizeof(filename));\n\t} else if(c + 1 &lt; argc) {\n\t  strncpy(filename, argv&#91;c + 1], sizeof(filename));\n\t  c++;\n\t}\n\tif(printcomma)\n\t  fprintf(stderr,\", \");\n\telse\n\t  printcomma = 0;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tterttuutilversion();\n#ifdef SHA256\n\tfprintf(stderr,\"\\nsha256(\");\n\tfor(int c = 0; c &lt; HashLen; c++) {\n\t  fprintf(stderr, \"%02x\", programfiledigest&#91;c]);\n\t}\n\tfprintf(stderr, \")\\n\\n\");\n#endif\n\thelp = 0;\n\texit(1);\n\n      } else if(!strcmp(\"--stat\", argv&#91;c])) {\n\tstat = !stat;\n\t\n      } else if(!strcmp(\"--query\", argv&#91;c])) {\n\tqueryflag = !queryflag;\n\t\n      } else if(!strcmp(\"--test\", argv&#91;c])) {\n\ttestflag = !testflag;\n\t\n      } else if(!strcmp(\"--test2\", argv&#91;c])) {\n\ttest2flag = !test2flag;\n\t\n      }\n    } else {\n      if(!first)\n\tstrcat(command, \" \");\n      strcat(command, argv&#91;c]);\n      first = 0;\n    }\n  }\n\n  db6_setheaderflags(\"headerfields\", 0);\n  db6_setheaderflags(\"linesfields\", 0);\n  db6_setheaderflags(\"header\", 0);\n  db6_setheaderflags(\"lines\", 0);\n  db6_setheaderflags(\"user\", 0);\n  db6_setheaderflags(\"log\", 0);\n  db6_setheaderflags(\"session\", 0);\n\n  more_init();\n\n#define TEST_SETS 8192\n#define TEST_ITEMS 5\n  \/\/#define TEST_SETS 9\n  \/\/#define TEST_ITEMS 3\n  \n  if(testflag) {\n    \/\/ 'a'='1', 'b'='1', 'c'='1'\n    \/\/ 'a'='2', 'b'='1', 'c'='1'\n    \/\/ 'a'='3', 'b'='2', 'c'='1'\n    \/\/ 'a'='4', 'b'='2', 'c'='2'\n    \/\/ 'a'='5', 'b'='3', 'c'='2'\n    \/\/ 'a'='6', 'b'='3', 'c'='2'\n    \/\/ 'a'='7', 'b'='4', 'c'='3'\n    \/\/ 'a'='8', 'b'='4', 'c'='3'\n    \/\/ 'a'='9', 'b'='5', 'c'='3'\n    for(c = 0; c &lt; TEST_SETS; c++) {\n      first = 1;\n      for(d = 0; d &lt; TEST_ITEMS ; d++) {\n\tif(!first)\n\t  fprintf(stdout,\", \");\n\tfprintf(stdout,\"'%c'\", 'a' + d);\n\tfprintf(stdout,\" = \");\n\tfprintf(stdout,\"\\\"%d\\\"\", c \/ (d + 1) + 1);\n\tfirst = 0;\n      }\n      fprintf(stdout,\"\\n\");\n    }\n  }\n  \n  if(test2flag) {\n#define SEQUENTIAL 1\n#define RANDOM 2\n    \n    struct field {\n      unsigned char *fieldname;\n      int fieldtype;\n      int lowlimit;\n      int highlimit;\n      unsigned char *valuestring;\n    } fields&#91;] = {\n      { \"asno\", SEQUENTIAL, 0, 0,\"10%05d\" },\n      { \"asnimi\", SEQUENTIAL, 0,0, \"nimi: %d\" },\n      { \"asoso\", SEQUENTIAL, 0, 0, \"osoite: %d\" },\n      { \"aspono\", RANDOM, 0, 99999, \"postinumero%d\"},\n      { \"aspotmp\", RANDOM, 0, 50, \"postitmp %d\"},\n      { \"asry\", RANDOM, 0, 10, \"1%d\"},\n      { \"asmail\", RANDOM, 0, 10, \"mail: %d\"},\n    };\n\n    stream_open(0, \"kalakala\");\n    \n    for(c = 0; c &lt; TEST_SETS; c++) {\n      if(quitcmd)\n\tbreak;\n\n      first = 1;\n\n      for(d = 0; d &lt; sizeof(fields) \/ sizeof(fields&#91;0]); d++) {\n\tif(!first)\n\t  more_printf(stdout,\", \");\n\tmore_printf(stdout,\"'%s'\", fields&#91;d].fieldname);\n\tmore_printf(stdout,\" = \");\n\tmore_printf(stdout,\"\\\"\");\n\tif(fields&#91;d].fieldtype = RANDOM &amp;&amp; (fields&#91;d].lowlimit != 0 || fields&#91;d].highlimit != 0)) {\n\t  unsigned int e = stream_gen_limit(fields&#91;d].highlimit - fields&#91;d].lowlimit) + fields&#91;d].lowlimit;\n\t  more_printf(stdout, fields&#91;d].valuestring, e);\n\t} else {\n\t  more_printf(stdout, fields&#91;d].valuestring, c);\n\t}\n\tmore_printf(stdout,\"\\\"\");\n\tfirst = 0;\n      }\n      more_printf(stdout,\"\\n\");\n    }\n    more_printf(stdout,\"\\n\");\n  }\n  \n  if(printcomma)\n    fprintf(stderr,\", \");\n  else\n    printcomma = 0;\n  \n  int count;\n  static unsigned char *query = NULL;\n  static int querylen = 0;\n  unsigned char *q;\n\n  \/\/querylen = 1;\n  \/\/query = realloc(query, querylen);;\n  querylen = 0;\n  query = NULL;\n\n  if(!queryflag &amp;&amp; strlen(command) != 0) {\n    util_parsequery(&amp;querylen, &amp;query, command);\n    util_doquery(query, filename);\n  }\n\n  int quit = 0;\n\n  unsigned char *command2 = NULL;\n  int command2len = 0;\n  \n  if(queryflag) {\n    while(!quit) {\n\n      more_init();\n\n      fprintf(stdout,\"skk&gt;\");\n      util_fgets(&amp;command2len, &amp;command2, stdin);\n      if(command2&#91;strlen(command) - 1] == '\\n')\n\tcommand2&#91;strlen(command) - 1] = '\\0';\n      if(strlen(command2)==0)\n\tcontinue;\n\n      more_printf(stdout, \"commandlen:%d\\n\", command2len);\n\n      if(!strcmp(command2,\"quit\"))\n\tquit = 1;\n      else if(!strcmp(command2,\"exit\"))\n\tquit = 1;\n      else if(!strcmp(command2,\"dumpsh\"))\n\tdb6_dumpsetheaders();\n      else if(!strcmp(command2,\"dumps\"))\n\tdb6_dumpsets();\n      else {\n\tutil_parsequery(&amp;querylen, &amp;query, command2);\n\tutil_doquery(query, filename);\n      }\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 esimerkkej\u00e4 terttuutil1:n ajosta: (ensimm\u00e4isess\u00e4 ilman komentoriviparametreja ajettu ajo antaa tulokseksi koko testimateriaalin (poista , line: ja `:t datasta).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/terttuutil1\nstat, command:``, query: ``\n, line: `'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n, line: `'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\n, line: `'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n, line: `'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\n, line: `'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\n, line: `'a' = \"6\", 'b' = \"3\", 'c' = \"2\"`\n, line: `'a' = \"7\", 'b' = \"4\", 'c' = \"2\"`\n, line: `'a' = \"8\", 'b' = \"4\", 'c' = \"2\"`\n\n$ .\/terttuutil1 a=1\nstat, command:`a=1`, added:, query: `'a' = \"1\"`\n, line: `'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n\n$ .\/terttuutil1 a=2\nstat, command:`a=2`, added:, query: `'a' = \"2\"`\n, line: `'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\n\n$ .\/terttuutil1 a=3\nstat, command:`a=3`, added:, query: `'a' = \"3\"`\n, line: `'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n\n$ .\/terttuutil1 a=4\nstat, command:`a=4`, added:, query: `'a' = \"4\"`\n, line: `'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\n\n$ .\/terttuutil1 b=1\nstat, command:`b=1`, added:, query: `'b' = \"1\"`\n, line: `'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n, line: `'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\n\n$ .\/terttuutil1 b=2\nstat, command:`b=2`, added:, query: `'b' = \"2\"`\n, line: `'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n, line: `'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\n\n$ .\/terttuutil1 b=3\nstat, command:`b=3`, added:, query: `'b' = \"3\"`\n, line: `'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\n, line: `'a' = \"6\", 'b' = \"3\", 'c' = \"2\"`\n\n$ .\/terttuutil1 b=4\nstat, command:`b=4`, added:, query: `'b' = \"4\"`\n, line: `'a' = \"7\", 'b' = \"4\", 'c' = \"2\"`\n, line: `'a' = \"8\", 'b' = \"4\", 'c' = \"2\"`\n\n$ .\/terttuutil1 c=1\nstat, command:`c=1`, added:, query: `'c' = \"1\"`\n, line: `'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n, line: `'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\n, line: `'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n, line: `'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\n\n$ .\/terttuutil1 c=2\nstat, command:`c=2`, added:, query: `'c' = \"2\"`\n, line: `'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\n, line: `'a' = \"6\", 'b' = \"3\", 'c' = \"2\"`\n, line: `'a' = \"7\", 'b' = \"4\", 'c' = \"2\"`\n, line: `'a' = \"8\", 'b' = \"4\", 'c' = \"2\"`\n$ <\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty terttuutil1:een &#8211;query toiminto, joka on hieman interaktiivisempi versio siit\u00e4: t\u00e4ss\u00e4 esimerkki ajosta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/terttuutil1 --query\ncommand:``, query:`(null)`, command:``, count:0\n**********querylen:0, count:1, query:`(null)`\n, query:``, command:``, count:0\n**********querylen:1, count:1, query:``\n`'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n`'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\n`'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n`'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\n`'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\n`'a' = \"6\", 'b' = \"3\", 'c' = \"2\"`\n`'a' = \"7\", 'b' = \"4\", 'c' = \"2\"`\n`'a' = \"8\", 'b' = \"4\", 'c' = \"2\"`\nskk&gt;a=1\n`a=1`\n, query:``, command:``, count:9\n**********querylen:1, count:10, query:``\n, query:`'a' = \"1\"`, command:``, count:9\n**********querylen:10, count:10, query:`'a' = \"1\"`\n`'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\nskk&gt;a=2\n`a=2`\n, query:`'a' = \"2\"`, command:``, count:9\n**********querylen:10, count:10, query:`'a' = \"2\"`\n`'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\nskk&gt;a=3\n`a=3`\n, query:`'a' = \"3\"`, command:``, count:9\n**********querylen:10, count:10, query:`'a' = \"3\"`\n`'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\nskk&gt;a=4\n`a=4`\n, query:`'a' = \"4\"`, command:``, count:9\n**********querylen:10, count:10, query:`'a' = \"4\"`\n`'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\nskk&gt;a=5\n`a=5`\n, query:`'a' = \"5\"`, command:``, count:9\n**********querylen:10, count:10, query:`'a' = \"5\"`\n`'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\nskk&gt;b=1\n`b=1`\n, query:`'b' = \"1\"`, command:``, count:9\n**********querylen:10, count:10, query:`'b' = \"1\"`\n`'a' = \"1\", 'b' = \"1\", 'c' = \"1\"`\n`'a' = \"2\", 'b' = \"1\", 'c' = \"1\"`\nskk&gt;b=2\n`b=2`\n, query:`'b' = \"2\"`, command:``, count:9\n**********querylen:10, count:10, query:`'b' = \"2\"`\n`'a' = \"3\", 'b' = \"2\", 'c' = \"1\"`\n`'a' = \"4\", 'b' = \"2\", 'c' = \"1\"`\nskk&gt;b=3\n`b=3`\n, query:`'b' = \"3\"`, command:``, count:9\n**********querylen:10, count:10, query:`'b' = \"3\"`\n`'a' = \"5\", 'b' = \"3\", 'c' = \"2\"`\n`'a' = \"6\", 'b' = \"3\", 'c' = \"2\"`\nskk&gt;b=4\n`b=4`\n, query:`'b' = \"4\"`, command:``, count:9\n**********querylen:10, count:10, query:`'b' = \"4\"`\n`'a' = \"7\", 'b' = \"4\", 'c' = \"2\"`\n`'a' = \"8\", 'b' = \"4\", 'c' = \"2\"`\nskk&gt;quit\n`quit`\n, query:`'quit'`, command:``, count:6\n**********querylen:10, count:7, query:`'quit'`\n$ <\/code><\/pre>\n\n\n\n<p>Seuraavassa viel\u00e4 uudemman terttuutil1:n tuloste, t\u00e4ll\u00e4 kertaa DEBUG66:lla<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/terttuutil1 --query\nadded set `headerfields`\nadded set `linesfields`\nadded set `header`\nadded set `lines`\nadded set `user`\nadded set `log`\nadded set `session`\nskk&gt;a\ncommandlen:2\ncommand:`a`, query:`'a'`\nadded set `project`\nDeleting chain `project`\nChain `project` deleted\nAdding chain `project`, set `'a' = \"1\"`\nAdding chain `project`, set `'a' = \"2\"`\nAdding chain `project`, set `'a' = \"3\"`\nAdding chain `project`, set `'a' = \"4\"`\nAdding chain `project`, set `'a' = \"5\"`\nAdding chain `project`, set `'a' = \"6\"`\nAdding chain `project`, set `'a' = \"7\"`\nAdding chain `project`, set `'a' = \"8\"`\nRestoring chain `project`, set `'a' = \"8\"`\n0*`'a' = \"8\"`\nRestoring chain `project`, set `'a' = \"7\"`\n1*`'a' = \"7\"`\nRestoring chain `project`, set `'a' = \"6\"`\n2*`'a' = \"6\"`\nRestoring chain `project`, set `'a' = \"5\"`\n3*`'a' = \"5\"`\nRestoring chain `project`, set `'a' = \"4\"`\n4*`'a' = \"4\"`\nRestoring chain `project`, set `'a' = \"3\"`\n5*`'a' = \"3\"`\nRestoring chain `project`, set `'a' = \"2\"`\n6*`'a' = \"2\"`\nRestoring chain `project`, set `'a' = \"1\"`\n7*`'a' = \"1\"`\nskk&gt;b\ncommandlen:2\ncommand:`b`, query:`'b'`\nDeleting chain `project`\nDeleting:'a' = \"8\"\nDeleting:'a' = \"7\"\nDeleting:'a' = \"6\"\nDeleting:'a' = \"5\"\nDeleting:'a' = \"4\"\nDeleting:'a' = \"3\"\nDeleting:'a' = \"2\"\nDeleting:'a' = \"1\"\nChain `project` deleted\nAdding chain `project`, set `'b' = \"1\"`\nAdding chain `project`, set `'b' = \"2\"`\nAdding chain `project`, set `'b' = \"3\"`\nAdding chain `project`, set `'b' = \"4\"`\nRestoring chain `project`, set `'b' = \"4\"`\n0*`'b' = \"4\"`\nRestoring chain `project`, set `'b' = \"3\"`\n1*`'b' = \"3\"`\nRestoring chain `project`, set `'b' = \"2\"`\n2*`'b' = \"2\"`\nRestoring chain `project`, set `'b' = \"1\"`\n3*`'b' = \"1\"`\nskk&gt;c\ncommandlen:2\ncommand:`c`, query:`'c'`\nDeleting chain `project`\nDeleting:'b' = \"4\"\nDeleting:'b' = \"3\"\nDeleting:'b' = \"2\"\nDeleting:'b' = \"1\"\nChain `project` deleted\nAdding chain `project`, set `'c' = \"1\"`\nAdding chain `project`, set `'c' = \"2\"`\nRestoring chain `project`, set `'c' = \"2\"`\n0*`'c' = \"2\"`\nRestoring chain `project`, set `'c' = \"1\"`\n1*`'c' = \"1\"`\nskk&gt;     <\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 mallirivej\u00e4 ilman DEBUG66:sta: N\u00e4ist\u00e4 huomaa helposti, ett\u00e4 tuplatietueiden poisto toimii, mutta lajittelu (sort) ei viel\u00e4 toimi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/terttuutil1 --query\nskk&gt;a\ncommandlen:2\ncommand:`a`, query:`'a'`\n0*`'a' = \"8\"`\n1*`'a' = \"7\"`\n2*`'a' = \"6\"`\n3*`'a' = \"5\"`\n4*`'a' = \"4\"`\n5*`'a' = \"3\"`\n6*`'a' = \"2\"`\n7*`'a' = \"1\"`\nskk&gt;b\ncommandlen:2\ncommand:`b`, query:`'b'`\n0*`'b' = \"4\"`\n1*`'b' = \"3\"`\n2*`'b' = \"2\"`\n3*`'b' = \"1\"`\nskk&gt;c\ncommandlen:2\ncommand:`c`, query:`'c'`\n0*`'c' = \"2\"`\n1*`'c' = \"1\"`\nskk&gt;a=1\ncommandlen:4\ncommand:`a=1`, query:`'a' = \"1\"`\n0*`'a' = \"1\"`\nskk&gt;b=2\ncommandlen:4\ncommand:`b=2`, query:`'b' = \"2\"`\n0*`'b' = \"2\"`\nskk&gt;c=3\ncommandlen:4\ncommand:`c=3`, query:`'c' = \"3\"`\nskk&gt;b=1\ncommandlen:4\ncommand:`b=1`, query:`'b' = \"1\"`\n0*`'b' = \"1\"`\nskk&gt;b=2\ncommandlen:4\ncommand:`b=2`, query:`'b' = \"2\"`\n0*`'b' = \"2\"`\nskk&gt;b=3\ncommandlen:4\ncommand:`b=3`, query:`'b' = \"3\"`\n0*`'b' = \"3\"`\nskk&gt;exit<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 uudempi testimateriaalien hakuja sis\u00e4lt\u00e4v\u00e4 lista, jossa lajittelukin toimii:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/terttuutil1 --query --filenameterttuutil1.skk\nskk&gt;a\ncommandlen:3\ncommand:`a`, query:`'a'`\n0*`'a' = \"1\"`\n1*`'a' = \"2\"`\n2*`'a' = \"3\"`\n3*`'a' = \"4\"`\n4*`'a' = \"5\"`\n5*`'a' = \"6\"`\n6*`'a' = \"7\"`\n7*`'a' = \"8\"`\nskk&gt;b\ncommandlen:3\ncommand:`b`, query:`'b'`\n0*`'b' = \"1\"`\n1*`'b' = \"2\"`\n2*`'b' = \"3\"`\n3*`'b' = \"4\"`\nskk&gt;c\ncommandlen:3\ncommand:`c`, query:`'c'`\n0*`'c' = \"1\"`\n1*`'c' = \"2\"`\nskk&gt;exit\ncommandlen:6\n$ <\/code><\/pre>\n\n\n\n<p>Seuraavaksi jatkan satunnaisten lippujen arpomista. K\u00e4yn l\u00e4pi newressu koodin lippujen osalta: Ensimm\u00e4isen\u00e4 p\u00e4tk\u00e4 lippujen talletusrakenteesta. Seuraava kuva listaa maailman maiden liput, ja niiden erilaiset valintakriteerit. Jos esimerkiksi haluamme &#8220;arvontaan&#8221; suomen lipun voimme tehd\u00e4 sen newressun komentorivioptioilla &#8211;fi, &#8211;fin, &#8211;finland, &#8211;Fi, &#8211;Fin, &#8211;Finland, &#8211;FI, &#8211;FIN, &#8211;FINLAND. Toivon ett\u00e4 my\u00f6s &#8211;\ud83c\uddeb\ud83c\uddee tulee olemaan mahdollinen. Huomaa ett\u00e4 isolla kirjoitetut ovat suurempia ryhmi\u00e4, joihin kuuluu useampia maita, esimerkiksi suomen &#8211;FINLAND tapauksessa ryhm\u00e4\u00e4n kuuluu ahvenanmaa (\u00e5land). Muita muita ryhmi\u00e4, joihin suomi t\u00e4ss\u00e4 yhteydess\u00e4 kuuluu ovat &#8211;EU, &#8211;EUROPE ja &#8211;NORDIC. Jos halutaan kaikki ryhm\u00e4\u00e4n kuuluvat kirjoitetaan komentorivioptioksi ryhm\u00e4n nimi. T\u00e4ss\u00e4 my\u00f6s muita kuin standardia asciita sis\u00e4lt\u00e4v\u00e4t maat on kirjoitettu pelk\u00e4ll\u00e4 asciilla, kuten \u00e5land = aland ja Cura\u00e7ao = curacao.<\/p>\n\n\n\n<p>Ensimm\u00e4inen kaksi merkkinen ascii &#8220;sana&#8221; (esimerkiksi suomen tapauksessa fi) on kaksi merkkinen isokoodi, ja kolmemerkkinen sana (suomen tapauksessa fin) on kolmemerkkinen isokoodi. Seuraavana iso-koodien j\u00e4lkeen tuleva merkkijono on maan nimi ilman v\u00e4lily\u00f6ntej\u00e4 (finland), ja loput isolla kirjoitetut ovat ryhmi\u00e4, joihin rivin maa kuuluu. T\u00e4ss\u00e4 lopun isoilla kirjoitetulla FINLAND sanalla suomi yhdistet\u00e4\u00e4n ahvenanmaahan. Lopussa on viel\u00e4 ryhm\u00e4t EU, EUROPE ja NORDIC.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct idflags { \/\/ 202307 JariK\n  unsigned char *id;\n  unsigned char *flags;\n} idsflags&#91;] = {\n  { \"\ud83c\uddeb\ud83c\uddee\", \"\ud83c\uddeb\ud83c\uddee: fi, fin, finland, EU, EUROPE, NORDIC, FINLAND\" },\n  { \"\ud83c\udde6\ud83c\uddfd\", \"\ud83c\udde6\ud83c\uddfd: ax, ala, \u00e5land, aland, EU, EUROPE, NORDIC, FINLAND\" },\n  { \"\ud83c\uddf8\ud83c\uddea\", \"\ud83c\uddf8\ud83c\uddea: se, swe, sweden, EU, EUROPE, NORDIC\" },\n  { \"\ud83c\uddf3\ud83c\uddf4\", \"\ud83c\uddf3\ud83c\uddf4: no, nor, norway, EU, EUROPE, NORDIC\" },\n  { \"\ud83c\udde9\ud83c\uddf0\", \"\ud83c\udde9\ud83c\uddf0: dk, dnk, denmark, EU, EUROPE, NORDIC, DENMARK\" },\n  { \"\ud83c\uddeb\ud83c\uddf4\", \"\ud83c\uddeb\ud83c\uddf4: fo, fro, FaroeIslands, EU, EUROPE, NORDIC, DENMARK\" },\n  { \"\ud83c\uddee\ud83c\uddf8\", \"\ud83c\uddee\ud83c\uddf8: is, isl, iceland, EU, EUROPE, NORDIC\" },\n  { \"\ud83c\uddea\ud83c\uddea\", \"\ud83c\uddea\ud83c\uddea: ee, est, estonia, EU, EUROPE, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddfb\", \"\ud83c\uddf1\ud83c\uddfb: lv, lva, latvia, EU, EUROPE, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddf9\", \"\ud83c\uddf1\ud83c\uddf9: lt, ltu, lithuania, EU, EUROPE, BALTIC\" },\n...\n\/\/ you can find full structure in the\n\/\/ beginning of this article or in the\n\/\/ full source of newressu in the end\n\/\/ of the article.\n...\n  { \"\ud83c\udde8\ud83c\uddfb\", \"\ud83c\udde8\ud83c\uddfb: cv, cpv, CapeVerde, AFRICA\" },\n  { \"\ud83c\uddea\ud83c\udded\", \"\ud83c\uddea\ud83c\udded: eh, esh, WesternSahara, AFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf9\", \"\ud83c\uddf8\ud83c\uddf9: st, stp, S\u00e3oTom\u00e9andPr\u00edncipe, saotomeandprincipe, AFRICA\" },\n  { \"\ud83c\uddf8\ud83c\udde8\", \"\ud83c\uddf8\ud83c\udde8: sc, syc, Seychelles, AFRICA\" },\n\n  { \"\ud83c\udde6\ud83c\uddfa\", \"\ud83c\udde6\ud83c\uddfa: au, aus, Australia\" },\n};<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 esimerkiksi komento suomen ja ruotsin lippujen arpomiseksi: (komento ei viel\u00e4 t\u00e4t\u00e4 kirjoittaessani arponut lippuja oikeasti, mutta nyt kun luet t\u00e4t\u00e4 olen varmasti koodannut arpomisen loppuun&#8230;)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --fi --se --flags\n00000 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00001 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\n00002 \ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\n00003 \ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\n00004 \ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\n00005 \ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\n00006 \ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\n00007 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\n00008 \ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\n00009 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 pohjoismaiden (&#8211;NORDIC) maiden komentoesimerkki:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --nordic --flags\n00000 \ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddee\ud83c\uddf8\n00001 \ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\uddec\ud83c\uddf1\ud83c\udde9\ud83c\uddf0\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddee\ud83c\uddf8\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\n00002 \ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf8\n00003 \ud83c\udde9\ud83c\uddf0\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\udde9\ud83c\uddf0\ud83c\udde9\ud83c\uddf0\ud83c\udde6\ud83c\uddfd\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddf8\ud83c\uddea\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\n00004 \ud83c\udde6\ud83c\uddfd\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddf3\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\n00005 \ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddee\ud83c\udde6\ud83c\uddfd\ud83c\uddf3\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\uddf3\ud83c\uddf4\n00006 \ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\udde9\ud83c\uddf0\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddee\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\n00007 \ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\udde9\ud83c\uddf0\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddf3\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\n00008 \ud83c\uddeb\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\uddeb\ud83c\uddee\ud83c\uddec\ud83c\uddf1\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf1\n00009 \ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf4\ud83c\uddee\ud83c\uddf8\ud83c\uddee\ud83c\uddf8\ud83c\uddec\ud83c\uddf1\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddee\ud83c\uddf8\ud83c\udde6\ud83c\uddfd\ud83c\uddee\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\udde6\ud83c\uddfd\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\uddf8\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\udde6\ud83c\uddfd\ud83c\uddeb\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\udde6\ud83c\uddfd\ud83c\uddec\ud83c\uddf1\ud83c\uddf3\ud83c\uddf4\ud83c\uddeb\ud83c\uddf4\ud83c\uddf3\ud83c\uddf4\ud83c\uddec\ud83c\uddf1\ud83c\udde9\ud83c\uddf0\ud83c\uddec\ud83c\uddf1\n$ <\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 eu:n lippuesimerkki:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --eu --flags\n00000 \ud83c\uddf1\ud83c\uddfa\ud83c\udde6\ud83c\uddf9\ud83c\uddf5\ud83c\uddf1\ud83c\uddea\ud83c\uddea\ud83c\uddf8\ud83c\uddf0\ud83c\udde9\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\udde7\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\udde7\ud83c\uddea\ud83c\udde7\ud83c\uddea\ud83c\uddf5\ud83c\uddf9\ud83c\udde8\ud83c\uddff\ud83c\uddf5\ud83c\uddf1\ud83c\udde9\ud83c\uddea\ud83c\uddf7\ud83c\uddf4\ud83c\uddeb\ud83c\uddf7\ud83c\uddf1\ud83c\uddfb\ud83c\uddf2\ud83c\uddf9\ud83c\uddea\ud83c\uddea\ud83c\uddf3\ud83c\uddf1\ud83c\uddf2\ud83c\uddf9\ud83c\uddec\ud83c\uddf7\ud83c\uddea\ud83c\uddf8\ud83c\uddf5\ud83c\uddf9\ud83c\uddeb\ud83c\uddee\ud83c\uddf2\ud83c\uddf9\ud83c\uddf5\ud83c\uddf9\ud83c\uddf8\ud83c\uddf0\ud83c\uddf3\ud83c\uddf1\n00001 \ud83c\udded\ud83c\uddf7\ud83c\udde7\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\uddf5\ud83c\uddf1\ud83c\udde9\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\uddf8\ud83c\uddee\ud83c\udded\ud83c\uddfa\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddec\ud83c\uddf7\ud83c\uddf2\ud83c\uddf9\ud83c\udde7\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\uddeb\ud83c\uddf7\ud83c\uddf3\ud83c\uddf1\ud83c\uddf8\ud83c\uddf0\ud83c\udde9\ud83c\uddea\ud83c\uddeb\ud83c\uddf7\ud83c\udde7\ud83c\uddea\ud83c\uddec\ud83c\uddf7\ud83c\uddf5\ud83c\uddf9\ud83c\uddf8\ud83c\uddf0\ud83c\udded\ud83c\uddf7\ud83c\udde7\ud83c\uddec\ud83c\uddeb\ud83c\uddf7\n00002 \ud83c\uddf8\ud83c\uddee\ud83c\uddf8\ud83c\uddee\ud83c\uddeb\ud83c\uddf7\ud83c\uddf8\ud83c\uddf0\ud83c\uddf1\ud83c\uddfa\ud83c\uddf5\ud83c\uddf9\ud83c\uddec\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\uddf8\ud83c\uddee\ud83c\uddf5\ud83c\uddf9\ud83c\uddf2\ud83c\uddf9\ud83c\uddf7\ud83c\uddf4\ud83c\uddf1\ud83c\uddfb\ud83c\uddee\ud83c\uddea\ud83c\udde7\ud83c\uddec\ud83c\uddea\ud83c\uddf8\ud83c\udde8\ud83c\uddfe\ud83c\uddee\ud83c\uddea\ud83c\uddf1\ud83c\uddfa\ud83c\uddf1\ud83c\uddf9\ud83c\uddf2\ud83c\uddf9\ud83c\uddf8\ud83c\uddf0\ud83c\uddeb\ud83c\uddf7\ud83c\udded\ud83c\uddfa\ud83c\udde9\ud83c\uddf0\ud83c\udded\ud83c\uddfa\ud83c\uddf1\ud83c\uddfb\ud83c\uddf1\ud83c\uddf9\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf9\n00003 \ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf5\ud83c\uddf1\ud83c\uddf8\ud83c\uddf0\ud83c\uddee\ud83c\uddf9\ud83c\uddeb\ud83c\uddf7\ud83c\uddf3\ud83c\uddf1\ud83c\uddf8\ud83c\uddf0\ud83c\udded\ud83c\uddf7\ud83c\udded\ud83c\uddfa\ud83c\uddf8\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddea\ud83c\udde7\ud83c\uddea\ud83c\uddeb\ud83c\uddf7\ud83c\udde8\ud83c\uddfe\ud83c\uddf2\ud83c\uddf9\ud83c\udded\ud83c\uddfa\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf9\ud83c\udded\ud83c\uddf7\ud83c\uddeb\ud83c\uddee\ud83c\udde7\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\udde7\ud83c\uddea\ud83c\uddf7\ud83c\uddf4\ud83c\uddf1\ud83c\uddfb\ud83c\uddeb\ud83c\uddee\ud83c\udde7\ud83c\uddea\ud83c\uddea\ud83c\uddf8\n00004 \ud83c\uddec\ud83c\uddf7\ud83c\uddf8\ud83c\uddf0\ud83c\uddf1\ud83c\uddfa\ud83c\udde7\ud83c\uddec\ud83c\uddee\ud83c\uddea\ud83c\udde9\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddf0\ud83c\uddf7\ud83c\uddf4\ud83c\uddee\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\uddec\ud83c\uddf7\ud83c\udded\ud83c\uddfa\ud83c\uddf8\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\udde9\ud83c\uddf0\ud83c\uddf5\ud83c\uddf1\ud83c\uddf1\ud83c\uddf9\ud83c\uddee\ud83c\uddf9\ud83c\uddf1\ud83c\uddfa\ud83c\udded\ud83c\uddfa\ud83c\uddf8\ud83c\uddea\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddf5\ud83c\uddf1\ud83c\uddf1\ud83c\uddfa\ud83c\uddec\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\uddf7\ud83c\uddf4\n00005 \ud83c\udde9\ud83c\uddf0\ud83c\udded\ud83c\uddf7\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddf8\ud83c\uddee\ud83c\uddea\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\udde8\ud83c\uddfe\ud83c\uddf3\ud83c\uddf1\ud83c\uddf5\ud83c\uddf9\ud83c\uddeb\ud83c\uddee\ud83c\uddee\ud83c\uddea\ud83c\uddea\ud83c\uddf8\ud83c\uddf8\ud83c\uddf0\ud83c\udde8\ud83c\uddff\ud83c\uddea\ud83c\uddea\ud83c\uddeb\ud83c\uddee\ud83c\uddf3\ud83c\uddf1\ud83c\uddee\ud83c\uddf9\ud83c\uddf2\ud83c\uddf9\ud83c\uddea\ud83c\uddf8\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\udde7\ud83c\uddea\ud83c\udde9\ud83c\uddf0\ud83c\uddf8\ud83c\uddea\ud83c\udde7\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\uddf1\ud83c\uddf9\ud83c\udde8\ud83c\uddff\n00006 \ud83c\uddf5\ud83c\uddf1\ud83c\udde8\ud83c\uddff\ud83c\uddf8\ud83c\uddee\ud83c\uddee\ud83c\uddf9\ud83c\udde8\ud83c\uddfe\ud83c\uddeb\ud83c\uddee\ud83c\udde9\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\uddf3\ud83c\uddf1\ud83c\uddea\ud83c\uddea\ud83c\udded\ud83c\uddf7\ud83c\uddf7\ud83c\uddf4\ud83c\uddf1\ud83c\uddf9\ud83c\udde9\ud83c\uddea\ud83c\uddf8\ud83c\uddee\ud83c\uddf1\ud83c\uddfb\ud83c\uddf1\ud83c\uddfb\ud83c\uddf1\ud83c\uddfb\ud83c\udded\ud83c\uddf7\ud83c\uddf5\ud83c\uddf9\ud83c\udde8\ud83c\uddfe\ud83c\udded\ud83c\uddfa\ud83c\uddf5\ud83c\uddf9\ud83c\uddec\ud83c\uddf7\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\uddf1\ud83c\uddfb\ud83c\udde6\ud83c\uddf9\ud83c\udded\ud83c\uddfa\n00007 \ud83c\uddea\ud83c\uddf8\ud83c\uddf8\ud83c\uddee\ud83c\uddee\ud83c\uddf9\ud83c\uddeb\ud83c\uddf7\ud83c\udde8\ud83c\uddff\ud83c\udde7\ud83c\uddec\ud83c\udde7\ud83c\uddec\ud83c\uddec\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\udded\ud83c\uddf7\ud83c\uddec\ud83c\uddf7\ud83c\uddea\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\uddf7\ud83c\uddf4\ud83c\uddf8\ud83c\uddf0\ud83c\uddf8\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\uddf3\ud83c\uddf1\ud83c\udde6\ud83c\uddf9\ud83c\uddf8\ud83c\uddea\ud83c\uddec\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\udde6\ud83c\uddf9\ud83c\uddea\ud83c\uddf8\ud83c\uddea\ud83c\uddea\ud83c\udded\ud83c\uddfa\ud83c\uddea\ud83c\uddea\ud83c\uddf2\ud83c\uddf9\n00008 \ud83c\uddf7\ud83c\uddf4\ud83c\uddf2\ud83c\uddf9\ud83c\uddf8\ud83c\uddf0\ud83c\uddf8\ud83c\uddee\ud83c\uddea\ud83c\uddea\ud83c\uddee\ud83c\uddf9\ud83c\uddea\ud83c\uddea\ud83c\uddf5\ud83c\uddf9\ud83c\udde9\ud83c\uddf0\ud83c\uddf8\ud83c\uddf0\ud83c\udde8\ud83c\uddfe\ud83c\uddf1\ud83c\uddfb\ud83c\uddec\ud83c\uddf7\ud83c\uddf3\ud83c\uddf1\ud83c\uddeb\ud83c\uddf7\ud83c\uddea\ud83c\uddf8\ud83c\uddf5\ud83c\uddf9\ud83c\udde9\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\uddf8\ud83c\uddf0\ud83c\uddee\ud83c\uddf9\ud83c\udded\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\uddee\ud83c\uddf9\ud83c\udde6\ud83c\uddf9\ud83c\udded\ud83c\uddf7\ud83c\udde8\ud83c\uddff\ud83c\udde6\ud83c\uddf9\ud83c\uddf8\ud83c\uddee\ud83c\uddeb\ud83c\uddf7\n00009 \ud83c\uddf8\ud83c\uddea\ud83c\udde6\ud83c\uddf9\ud83c\uddf3\ud83c\uddf1\ud83c\uddf8\ud83c\uddee\ud83c\uddea\ud83c\uddf8\ud83c\uddf8\ud83c\uddee\ud83c\udde9\ud83c\uddf0\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf1\ud83c\uddfb\ud83c\uddeb\ud83c\uddee\ud83c\udde6\ud83c\uddf9\ud83c\udde9\ud83c\uddf0\ud83c\uddf1\ud83c\uddfa\ud83c\uddeb\ud83c\uddf7\ud83c\uddf5\ud83c\uddf9\ud83c\uddf3\ud83c\uddf1\ud83c\uddf2\ud83c\uddf9\ud83c\uddf8\ud83c\uddf0\ud83c\uddf5\ud83c\uddf1\ud83c\udde8\ud83c\uddfe\ud83c\udded\ud83c\uddf7\ud83c\uddeb\ud83c\uddf7\ud83c\uddf8\ud83c\uddee\ud83c\uddea\ud83c\uddea\ud83c\uddf3\ud83c\uddf1\ud83c\uddea\ud83c\uddf8\ud83c\uddee\ud83c\uddf9\ud83c\udde8\ud83c\uddfe\ud83c\uddf7\ud83c\uddf4\n$<\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 esimerkki lipun kuvalla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --\ud83c\uddeb\ud83c\uddee --flags\n00000 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00001 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00002 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00003 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00004 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00005 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00006 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00007 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00008 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n00009 \ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\ud83c\uddeb\ud83c\uddee\n$<\/code><\/pre>\n\n\n\n<p>AFRICA:n lippuja: (nyt on ruotsin lippu alarivill\u00e4 eksynyt. se oli itseasiassa komennossa&#8230;)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --AFRICA --flags\n00000 \ud83c\uddfa\ud83c\uddec\ud83c\uddf9\ud83c\uddec\ud83c\uddf2\ud83c\uddff\ud83c\udde8\ud83c\uddee\ud83c\uddea\ud83c\uddf9\ud83c\uddf8\ud83c\uddf1\ud83c\udde7\ud83c\uddee\ud83c\udde7\ud83c\uddee\ud83c\uddf2\ud83c\uddff\ud83c\uddec\ud83c\uddf3\ud83c\uddf2\ud83c\uddfa\ud83c\uddfe\ud83c\uddf9\ud83c\uddf1\ud83c\uddf7\ud83c\uddf1\ud83c\uddfe\ud83c\uddf2\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddf1\ud83c\uddfa\ud83c\uddec\ud83c\udde9\ud83c\uddff\ud83c\uddec\ud83c\uddf2\ud83c\uddea\ud83c\uddf9\ud83c\uddec\ud83c\uddfc\ud83c\udde8\ud83c\udde9\ud83c\uddfa\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\udde9\ud83c\uddff\ud83c\uddec\ud83c\udde6\ud83c\uddf8\ud83c\uddf1\ud83c\uddf2\ud83c\uddfa\ud83c\uddf2\ud83c\uddf7\n00001 \ud83c\udde6\ud83c\uddf4\ud83c\uddf7\ud83c\uddfc\ud83c\uddff\ud83c\uddfc\ud83c\uddf2\ud83c\uddfa\ud83c\uddf2\ud83c\uddfc\ud83c\udde8\ud83c\udde9\ud83c\uddf8\ud83c\uddf3\ud83c\udde8\ud83c\uddfb\ud83c\uddea\ud83c\uddf9\ud83c\uddf2\ud83c\uddf7\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddf9\ud83c\uddf3\ud83c\uddea\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\uddf2\ud83c\uddf3\ud83c\uddea\ud83c\uddf2\ud83c\uddfa\ud83c\uddec\ud83c\udde6\ud83c\uddf8\ud83c\uddf3\ud83c\uddf8\ud83c\uddf3\ud83c\udde7\ud83c\uddee\ud83c\uddec\ud83c\uddf3\ud83c\uddea\ud83c\uddf7\ud83c\uddea\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\uddf9\ud83c\uddff\ud83c\udde9\ud83c\uddef\ud83c\udde8\ud83c\uddfb\ud83c\udde8\ud83c\uddee\ud83c\uddec\ud83c\udded\n00002 \ud83c\udde8\ud83c\udde9\ud83c\uddf1\ud83c\uddfe\ud83c\uddf0\ud83c\uddf2\ud83c\uddf1\ud83c\uddf7\ud83c\uddf1\ud83c\uddfe\ud83c\udde7\ud83c\uddef\ud83c\uddf2\ud83c\uddf7\ud83c\uddf9\ud83c\uddec\ud83c\uddf8\ud83c\udde9\ud83c\uddea\ud83c\udded\ud83c\uddf8\ud83c\uddf8\ud83c\uddf2\ud83c\uddfa\ud83c\uddf9\ud83c\udde9\ud83c\uddea\ud83c\uddf7\ud83c\udde8\ud83c\uddee\ud83c\uddff\ud83c\uddf2\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddef\ud83c\uddea\ud83c\uddf7\ud83c\uddfa\ud83c\uddec\ud83c\uddf3\ud83c\udde6\ud83c\uddea\ud83c\uddec\ud83c\udde8\ud83c\udde9\ud83c\uddfe\ud83c\uddf9\ud83c\uddf2\ud83c\uddff\ud83c\uddfa\ud83c\uddec\ud83c\uddf8\ud83c\uddf3\ud83c\udde8\ud83c\uddfb\ud83c\uddf9\ud83c\udde9\ud83c\udde9\ud83c\uddff\n00003 \ud83c\uddf2\ud83c\uddfa\ud83c\udde7\ud83c\uddef\ud83c\uddf3\ud83c\udde6\ud83c\udde8\ud83c\uddee\ud83c\udde6\ud83c\uddf4\ud83c\uddf7\ud83c\uddea\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddf9\ud83c\uddf7\ud83c\uddfc\ud83c\uddf0\ud83c\uddea\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddef\ud83c\udde8\ud83c\uddf2\ud83c\uddf9\ud83c\uddec\ud83c\udde9\ud83c\uddef\ud83c\uddf8\ud83c\uddf1\ud83c\uddff\ud83c\uddf2\ud83c\udde8\ud83c\udde9\ud83c\udde8\ud83c\uddee\ud83c\udde8\ud83c\udde9\ud83c\udde8\ud83c\uddf2\ud83c\udde6\ud83c\uddf4\ud83c\uddf1\ud83c\uddfe\ud83c\uddf8\ud83c\uddf8\ud83c\uddf0\ud83c\uddea\ud83c\uddec\ud83c\udded\ud83c\uddf1\ud83c\uddf8\ud83c\uddf2\ud83c\uddfa\ud83c\uddf2\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\n00004 \ud83c\uddf0\ud83c\uddf2\ud83c\uddec\ud83c\udded\ud83c\uddf2\ud83c\uddff\ud83c\udde9\ud83c\uddef\ud83c\uddec\ud83c\udded\ud83c\uddff\ud83c\uddf2\ud83c\uddf9\ud83c\uddec\ud83c\udde9\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf7\ud83c\udde7\ud83c\uddee\ud83c\uddec\ud83c\udde6\ud83c\udde9\ud83c\uddff\ud83c\uddf2\ud83c\uddff\ud83c\uddf9\ud83c\uddff\ud83c\uddf8\ud83c\udde8\ud83c\uddf1\ud83c\uddf7\ud83c\uddff\ud83c\uddfc\ud83c\uddf2\ud83c\uddf1\ud83c\uddf7\ud83c\uddea\ud83c\uddf7\ud83c\uddea\ud83c\udde7\ud83c\uddeb\ud83c\uddf8\ud83c\uddf1\ud83c\uddec\ud83c\uddf3\ud83c\udde6\ud83c\uddf4\ud83c\uddf2\ud83c\uddfa\ud83c\udde8\ud83c\uddfb\ud83c\udde8\ud83c\uddf2\ud83c\uddf9\ud83c\uddff\ud83c\uddf9\ud83c\uddf3\n00005 \ud83c\uddf2\ud83c\uddff\ud83c\uddf7\ud83c\uddea\ud83c\uddea\ud83c\uddec\ud83c\uddfa\ud83c\uddec\ud83c\udde7\ud83c\uddef\ud83c\udde8\ud83c\uddfb\ud83c\uddf9\ud83c\udde9\ud83c\uddea\ud83c\uddf7\ud83c\uddf2\ud83c\uddff\ud83c\udde9\ud83c\uddef\ud83c\udde8\ud83c\udde9\ud83c\uddf0\ud83c\uddea\ud83c\udde8\ud83c\udde9\ud83c\udde8\ud83c\uddec\ud83c\udde8\ud83c\udde9\ud83c\uddf8\ud83c\udde9\ud83c\uddf2\ud83c\uddfa\ud83c\uddf1\ud83c\uddfe\ud83c\uddf2\ud83c\uddfa\ud83c\uddea\ud83c\uddf7\ud83c\udde7\ud83c\uddfc\ud83c\uddfe\ud83c\uddf9\ud83c\uddf8\ud83c\uddf8\ud83c\uddf2\ud83c\uddfa\ud83c\uddf9\ud83c\uddf3\ud83c\uddff\ud83c\uddf2\ud83c\uddf8\ud83c\udde9\ud83c\uddf8\ud83c\udde8\ud83c\uddf7\ud83c\uddea\ud83c\udde9\ud83c\uddff\n00006 \ud83c\uddf2\ud83c\uddfa\ud83c\uddec\ud83c\uddfc\ud83c\uddf8\ud83c\uddf8\ud83c\udde7\ud83c\uddee\ud83c\uddf2\ud83c\uddfa\ud83c\uddea\ud83c\uddf7\ud83c\uddea\ud83c\uddf9\ud83c\uddf2\ud83c\uddf7\ud83c\udde8\ud83c\uddec\ud83c\uddf2\ud83c\uddfa\ud83c\uddec\ud83c\uddf3\ud83c\uddf2\ud83c\udde6\ud83c\uddf8\ud83c\udde9\ud83c\uddf0\ud83c\uddea\ud83c\uddf8\ud83c\uddf3\ud83c\uddea\ud83c\uddec\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\uddfc\ud83c\uddec\ud83c\uddfc\ud83c\uddec\ud83c\udded\ud83c\uddf7\ud83c\uddfc\ud83c\uddf8\ud83c\uddf4\ud83c\uddea\ud83c\uddf7\ud83c\udde7\ud83c\uddef\ud83c\uddec\ud83c\uddf2\ud83c\udde8\ud83c\uddf2\ud83c\udde8\ud83c\uddee\ud83c\uddf8\ud83c\udde8\ud83c\uddf0\ud83c\uddea\ud83c\uddf2\ud83c\uddf7\n00007 \ud83c\uddea\ud83c\uddec\ud83c\uddf8\ud83c\uddf3\ud83c\uddec\ud83c\udde6\ud83c\uddec\ud83c\udded\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddfe\ud83c\udde6\ud83c\uddf4\ud83c\udde8\ud83c\uddee\ud83c\udde8\ud83c\udde9\ud83c\uddf9\ud83c\uddf3\ud83c\uddea\ud83c\uddec\ud83c\uddec\ud83c\uddf2\ud83c\uddf2\ud83c\uddff\ud83c\uddf9\ud83c\uddec\ud83c\uddec\ud83c\uddf2\ud83c\uddec\ud83c\uddf2\ud83c\uddf1\ud83c\uddf8\ud83c\uddec\ud83c\uddf3\ud83c\udde7\ud83c\uddeb\ud83c\udde9\ud83c\uddff\ud83c\uddf8\ud83c\uddf1\ud83c\uddf2\ud83c\uddec\ud83c\uddf1\ud83c\uddfe\ud83c\uddf1\ud83c\uddf7\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddf7\ud83c\uddf8\ud83c\uddf3\ud83c\uddf1\ud83c\uddf7\ud83c\uddea\ud83c\uddf9\ud83c\uddf9\ud83c\uddec\n00008 \ud83c\uddf2\ud83c\uddfc\ud83c\uddf1\ud83c\uddfe\ud83c\uddf8\ud83c\uddf4\ud83c\uddf2\ud83c\uddff\ud83c\uddff\ud83c\uddfc\ud83c\uddf2\ud83c\uddec\ud83c\uddf1\ud83c\uddf8\ud83c\udde8\ud83c\uddfb\ud83c\uddf8\ud83c\uddf8\ud83c\udde6\ud83c\uddf4\ud83c\uddf8\ud83c\uddf8\ud83c\uddf7\ud83c\uddfc\ud83c\uddec\ud83c\udde6\ud83c\uddf7\ud83c\uddea\ud83c\uddf8\ud83c\uddf8\ud83c\udde8\ud83c\uddec\ud83c\uddf1\ud83c\uddfe\ud83c\uddf2\ud83c\udde6\ud83c\uddf1\ud83c\uddfe\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddf1\ud83c\udde8\ud83c\uddf2\ud83c\uddec\ud83c\uddfc\ud83c\uddf3\ud83c\uddea\ud83c\uddf8\ud83c\udde8\ud83c\uddf3\ud83c\uddea\ud83c\uddf2\ud83c\uddf1\ud83c\uddea\ud83c\uddf7\ud83c\uddf7\ud83c\uddea\ud83c\uddec\ud83c\uddf3\n00009 \ud83c\uddea\ud83c\uddf7\ud83c\uddf8\ud83c\uddf8\ud83c\uddec\ud83c\udded\ud83c\udde8\ud83c\udde9\ud83c\udde8\ud83c\uddfb\ud83c\uddec\ud83c\uddf2\ud83c\uddf2\ud83c\uddf7\ud83c\uddf2\ud83c\uddfa\ud83c\uddf8\ud83c\udde8\ud83c\uddf2\ud83c\uddf7\ud83c\uddf9\ud83c\udde9\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddf1\ud83c\uddfa\ud83c\uddec\ud83c\udde8\ud83c\uddf2\ud83c\uddf8\ud83c\uddf8\ud83c\udde8\ud83c\uddee\ud83c\uddf7\ud83c\uddea\ud83c\uddf2\ud83c\uddfa\ud83c\uddf0\ud83c\uddf2\ud83c\uddf2\ud83c\uddf7\ud83c\uddf3\ud83c\uddea\ud83c\udde7\ud83c\uddef\ud83c\uddf3\ud83c\uddea\ud83c\udde8\ud83c\uddf2\ud83c\uddf8\ud83c\uddf8\ud83c\uddf9\ud83c\udde9\ud83c\udde8\ud83c\uddfb\ud83c\uddf8\ud83c\uddf8\ud83c\uddf8\ud83c\uddf8\n$<\/code><\/pre>\n\n\n\n<p>Etel\u00e4 afrikka: (SOUTHAFRICA)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --SOUTHAFRICA --flags\n00000 \ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\n00001 \ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\n00002 \ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\n00003 \ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\n00004 \ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\n00005 \ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\n00006 \ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\n00007 \ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\n00008 \ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddff\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\n00009 \ud83c\uddf8\ud83c\uddff\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf3\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\udde7\ud83c\uddfc\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf8\ud83c\uddff\ud83c\uddff\ud83c\udde6\ud83c\uddf1\ud83c\uddf8\ud83c\uddff\ud83c\udde6\ud83c\udde7\ud83c\uddfc\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddf3\ud83c\udde6\ud83c\uddf8\ud83c\uddff\ud83c\uddf1\ud83c\uddf8\ud83c\uddf8\ud83c\uddff\ud83c\udde7\ud83c\uddfc\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 lippuja &#8211;all optiolla: huomaa EquatorialGuinea:n lippu &#8220;cq&#8221;, joka tarkoittaa ett\u00e4 isokoodilla cq ei l\u00f6ytynyt utf8 lippua. Lis\u00e4tty muutamia puuttuvia maita.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --all --flags\n00000 \ud83c\uddef\ud83c\uddea\ud83c\udde8\ud83c\uddf7\ud83c\uddf2\ud83c\uddfd\ud83c\udde8\ud83c\uddff\ud83c\uddf0\ud83c\uddfc\ud83c\udde8\ud83c\uddf4\ud83c\uddf5\ud83c\uddeb\ud83c\uddf8\ud83c\uddf8\ud83c\uddec\ud83c\uddf3\ud83c\uddf9\ud83c\uddf0\ud83c\uddfb\ud83c\uddf3\ud83c\uddf0\ud83c\uddf5\ud83c\udde7\ud83c\uddfe\ud83c\uddf1\ud83c\uddfe\ud83c\uddfa\ud83c\uddfe\ud83c\uddf0\ud83c\uddea\ud83c\uddea\ud83c\uddea\ud83c\uddf5\ud83c\uddea\ud83c\udde6\ud83c\uddf8\ud83c\uddf5\ud83c\uddf9\ud83c\uddec\ud83c\uddfa\ud83c\uddf8\ud83c\uddf1\ud83c\uddec\ud83c\uddf1\ud83c\uddf0\ud83c\uddff\ud83c\uddf2\ud83c\uddfa\ud83c\uddeb\ud83c\uddef\ud83c\uddec\ud83c\uddf9\ud83c\uddf7\ud83c\uddf8\ud83c\uddf9\ud83c\uddef\ud83c\udde8\ud83c\uddee\n00001 \ud83c\uddeb\ud83c\uddf7\ud83c\uddfb\ud83c\uddea\ud83c\uddf0\ud83c\uddee\ud83c\udde9\ud83c\uddef\ud83c\uddec\ud83c\uddea\ud83c\uddea\ud83c\uddec\ud83c\uddf8\ud83c\uddf2\ud83c\uddf4\ud83c\uddf2\ud83c\uddf0\ud83c\uddee\ud83c\uddf0\ud83c\uddf5\ud83c\uddf8\ud83c\uddec\ud83c\uddf5\ud83c\uddfc\ud83c\uddf8\ud83c\udde7\ud83c\uddfb\ud83c\uddee\ud83c\udde9\ud83c\uddf4\ud83c\udde8\ud83c\uddf7\ud83c\uddf5\ud83c\uddf8\ud83c\uddf1\ud83c\uddf7\ud83c\udde9\ud83c\uddea\ud83c\udde7\ud83c\uddeb\ud83c\uddfe\ud83c\uddea\ud83c\uddec\ud83c\uddf2\ud83c\uddea\ud83c\uddec\ud83c\udde8\ud83c\uddfc\ud83c\uddec\ud83c\uddf8\ud83c\uddea\ud83c\udde8\ud83c\uddeb\ud83c\uddf7\ud83c\uddf0\ud83c\uddee\ud83c\uddfe\ud83c\uddea\ud83c\udde8\ud83c\uddf6\n00002 \ud83c\uddf9\ud83c\uddff\ud83c\udde6\ud83c\uddeb\ud83c\uddf5\ud83c\uddf7\ud83c\udde8\ud83c\uddf3\ud83c\uddf2\ud83c\uddfa\ud83c\uddf2\ud83c\uddf6\ud83c\uddf8\ud83c\uddfb\ud83c\uddfe\ud83c\uddf9\ud83c\uddf5\ud83c\uddfc\ud83c\uddf3\ud83c\udde6\ud83c\uddef\ud83c\uddea\ud83c\uddf9\ud83c\uddff\ud83c\udde7\ud83c\uddfc\ud83c\uddf3\ud83c\uddfa\ud83c\udded\ud83c\uddf0\ud83c\uddf9\ud83c\uddf2\ud83c\uddf2\ud83c\uddf7\ud83c\uddf5\ud83c\uddf3\ud83c\udde8\ud83c\uddfe\ud83c\uddfe\ud83c\uddea\ud83c\udde7\ud83c\uddf8\ud83c\uddf0\ud83c\uddee\ud83c\uddf2\ud83c\uddfa\ud83c\udde7\ud83c\uddfb\ud83c\uddf7\ud83c\uddf8\ud83c\uddf8\ud83c\uddee\ud83c\uddfe\ud83c\uddea\ud83c\uddf0\ud83c\uddf5\ud83c\udde8\ud83c\uddeb\ud83c\uddee\ud83c\uddf7\n00003 \ud83c\uddee\ud83c\uddea\ud83c\uddec\ud83c\uddee\ud83c\uddf0\ud83c\uddfc\ud83c\uddf5\ud83c\uddf7\ud83c\uddf8\ud83c\uddf7\ud83c\uddec\ud83c\uddf3\ud83c\uddeb\ud83c\uddf0\ud83c\uddf8\ud83c\uddfe\ud83c\udde9\ud83c\uddff\ud83c\udde7\ud83c\uddeb\ud83c\uddfb\ud83c\uddee\ud83c\uddff\ud83c\uddfc\ud83c\uddeb\ud83c\uddf7\ud83c\udded\ud83c\uddf0\ud83c\uddf1\ud83c\uddf7\ud83c\udde6\ud83c\uddf9\ud83c\uddf9\ud83c\uddec\ud83c\uddf8\ud83c\uddf3\ud83c\uddf3\ud83c\uddf5\ud83c\udde7\ud83c\uddf2\ud83c\uddf9\ud83c\uddff\ud83c\udde7\ud83c\udde6\ud83c\udde6\ud83c\uddf9\ud83c\uddf1\ud83c\uddf0\ud83c\uddf7\ud83c\uddfc\ud83c\uddf9\ud83c\uddef\ud83c\uddf3\ud83c\udde8\ud83c\udde7\ud83c\uddf8\ud83c\udde7\ud83c\uddfb\ud83c\udde8\ud83c\uddf1\n00004 \ud83c\uddf0\ud83c\uddf5\ud83c\uddee\ud83c\uddf6\ud83c\uddf0\ud83c\uddfc\ud83c\uddf0\ud83c\uddec\ud83c\uddf8\ud83c\uddf4\ud83c\udde8\ud83c\uddeb\ud83c\uddf5\ud83c\uddeb\ud83c\uddeb\ud83c\uddf7\ud83c\uddf8\ud83c\uddf4\ud83c\uddea\ud83c\uddf8\ud83c\uddf1\ud83c\uddf8\ud83c\uddea\ud83c\udded\ud83c\udde8\ud83c\udde9\ud83c\udde6\ud83c\uddf9\ud83c\uddf6\ud83c\udde6\ud83c\udde9\ud83c\uddf2\ud83c\uddec\ud83c\uddf3\ud83c\uddf2\ud83c\uddfb\ud83c\udde8\ud83c\uddf7\ud83c\uddea\ud83c\uddf8\ud83c\uddf0\ud83c\uddea\ud83c\uddf0\ud83c\uddfe\ud83c\uddf1\ud83c\uddfb\ud83c\uddee\ud83c\uddf3\ud83c\uddec\ud83c\uddfa\ud83c\udde8\ud83c\uddf6\ud83c\udde7\ud83c\uddf6\ud83c\uddf0\ud83c\uddf2\ud83c\uddf3\ud83c\uddf7\ud83c\uddf9\ud83c\udde9\n00005 \ud83c\uddfa\ud83c\uddff\ud83c\udde9\ud83c\uddf2\ud83c\uddf5\ud83c\uddf3\ud83c\udde8\ud83c\uddff\ud83c\udde7\ud83c\uddee\ud83c\udde7\ud83c\uddf4\ud83c\uddea\ud83c\uddea\ud83c\uddf2\ud83c\uddf9\ud83c\uddec\ud83c\uddfe\ud83c\uddf8\ud83c\uddfe\ud83c\uddf8\ud83c\udde7\ud83c\uddf5\ud83c\uddf8\ud83c\uddf1\ud83c\uddf7\ud83c\udde8\ud83c\udde6\ud83c\uddec\ud83c\udde9\ud83c\uddfb\ud83c\udde8\ud83c\uddee\ud83c\uddf7\ud83c\uddf2\ud83c\uddf6\ud83c\uddf5\ud83c\udded\ud83c\uddf8\ud83c\uddea\ud83c\uddf5\ud83c\uddf9\ud83c\uddf8\ud83c\uddee\ud83c\uddec\ud83c\uddec\ud83c\uddf1\ud83c\uddfe\ud83c\uddf2\ud83c\uddff\ud83c\uddf5\ud83c\uddf2\ud83c\uddfa\ud83c\uddfe\ud83c\uddfc\ud83c\uddf8\ud83c\uddf8\ud83c\uddf7\ud83c\uddec\ud83c\uddea\n00006 \ud83c\uddf1\ud83c\uddee\ud83c\uddeb\ud83c\uddf2\ud83c\uddfe\ud83c\uddf9\ud83c\uddea\ud83c\uddf9\ud83c\udde8\ud83c\uddff\ud83c\uddfb\ud83c\uddea\ud83c\uddee\ud83c\udde9\ud83c\uddf5\ud83c\uddea\ud83c\uddf2\ud83c\uddf1\ud83c\udde8\ud83c\uddf7\ud83c\uddf5\ud83c\uddf9\ud83c\uddf1\ud83c\uddf8\ud83c\uddf2\ud83c\uddff\ud83c\udde8\ud83c\uddf4\ud83c\udde8\ud83c\uddf6\ud83c\uddf3\ud83c\uddff\ud83c\udde6\ud83c\uddea\ud83c\uddec\ud83c\uddf7\ud83c\uddea\ud83c\udde8\ud83c\uddf8\ud83c\uddfd\ud83c\uddf8\ud83c\uddea\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\udde8\ud83c\uddfc\ud83c\uddeb\ud83c\uddee\ud83c\uddf7\ud83c\uddf1\ud83c\udde7\ud83c\udde9\ud83c\uddf0\ud83c\uddee\ud83c\uddf7\ud83c\uddfb\ud83c\uddea\ud83c\udde7\ud83c\udde7\n00007 \ud83c\uddf5\ud83c\uddfe\ud83c\udde8\ud83c\uddec\ud83c\uddfa\ud83c\uddfe\ud83c\uddf2\ud83c\uddf9\ud83c\uddf8\ud83c\udde6\ud83c\udde8\ud83c\uddf1\ud83c\udde8\ud83c\udde9\ud83c\uddf9\ud83c\uddf1\ud83c\uddf5\ud83c\uddfe\ud83c\uddf3\ud83c\uddfa\ud83c\uddec\ud83c\uddee\ud83c\uddf8\ud83c\uddf3\ud83c\uddeb\ud83c\uddf0\ud83c\uddff\ud83c\udde6\ud83c\udde6\ud83c\uddfc\ud83c\uddf2\ud83c\uddf0\ud83c\uddea\ud83c\uddec\ud83c\udde6\ud83c\uddf4\ud83c\udde7\ud83c\udde7\ud83c\uddf9\ud83c\udde9\ud83c\uddef\ud83c\uddf5\ud83c\uddfa\ud83c\uddfe\ud83c\uddf8\ud83c\uddea\ud83c\uddf9\ud83c\udde9\ud83c\uddec\ud83c\uddf5\ud83c\uddee\ud83c\udde9\ud83c\uddf8\ud83c\uddf4\ud83c\uddea\ud83c\uddf8\ud83c\uddfa\ud83c\uddfe\ud83c\udde8\ud83c\uddf2\n00008 \ud83c\uddec\ud83c\uddf5\ud83c\uddf2\ud83c\uddff\ud83c\uddf9\ud83c\udde8\ud83c\uddf9\ud83c\uddf1\ud83c\uddf9\ud83c\uddf9\ud83c\udde7\ud83c\uddfc\ud83c\uddfe\ud83c\uddea\ud83c\uddee\ud83c\uddf7\ud83c\uddf2\ud83c\uddf1\ud83c\uddf0\ud83c\uddea\ud83c\uddf9\ud83c\uddeb\ud83c\uddec\ud83c\udde9\ud83c\uddf1\ud83c\uddee\ud83c\uddf0\ud83c\uddff\ud83c\uddfe\ud83c\uddea\ud83c\udde8\ud83c\uddfe\ud83c\udde8\ud83c\uddfc\ud83c\uddec\ud83c\uddfa\ud83c\uddf3\ud83c\uddfa\ud83c\udde6\ud83c\uddf6\ud83c\uddf9\ud83c\uddff\ud83c\uddf2\ud83c\udde9\ud83c\uddf2\ud83c\uddff\ud83c\uddf2\ud83c\udde6\ud83c\uddf8\ud83c\uddf3\ud83c\uddf8\ud83c\uddfb\ud83c\uddeb\ud83c\uddf7\ud83c\uddf2\ud83c\uddfa\ud83c\uddf9\ud83c\uddf3\ud83c\udde9\ud83c\uddef\n00009 \ud83c\uddf2\ud83c\uddea\ud83c\uddf2\ud83c\uddeb\ud83c\uddf3\ud83c\uddea\ud83c\udded\ud83c\uddf3\ud83c\uddeb\ud83c\uddf7\ud83c\uddf5\ud83c\uddf3\ud83c\uddf2\ud83c\uddfd\ud83c\uddf7\ud83c\uddf8\ud83c\udde8\ud83c\udde9\ud83c\uddf2\ud83c\uddfb\ud83c\udde7\ud83c\uddef\ud83c\uddf0\ud83c\uddee\ud83c\uddf0\ud83c\uddea\ud83c\uddf5\ud83c\uddea\ud83c\uddf8\ud83c\uddfb\ud83c\uddf5\ud83c\uddf8\ud83c\uddf1\ud83c\uddee\ud83c\uddeb\ud83c\uddf0\ud83c\uddf2\ud83c\uddf1\ud83c\uddef\ud83c\uddf5\ud83c\uddf5\ud83c\uddea\ud83c\uddf8\ud83c\uddfd\ud83c\uddf7\ud83c\uddf4\ud83c\uddee\ud83c\uddea\ud83c\uddf8\ud83c\uddf2\ud83c\uddf2\ud83c\uddf2\ud83c\uddee\ud83c\uddf4\ud83c\uddfe\ud83c\uddf9\ud83c\udde8\ud83c\uddee\ud83c\uddfa\ud83c\uddf8\n$<\/code><\/pre>\n\n\n\n<p>Seuraavassa rutiini, jolle kaikki komentoriviparametrit annetaan, ja funktio merkkaa ne id:t (t\u00e4ss\u00e4 tapauksessa liput), jotka komentoriviparametri valitsee. Esimerkiksi &#8216;fi&#8217; k\u00e4\u00e4nt\u00e4\u00e4 suomen kytkimen, samalla tavoin kun aiemminkin komentorivikytkimet ovat toimineet. Jos komentorivill\u00e4 on useampia kytkimi\u00e4, jokaisella niist\u00e4 kutsutaan t\u00e4t\u00e4 erikseen. Jos ensin ensimm\u00e4inen kytkin valitsee &#8216;finland&#8217; lipun, se merkit\u00e4\u00e4n ensimm\u00e4isell\u00e4 kutsulla, ja jos sen j\u00e4lkeen valitaan &#8216;sweden&#8217;, se merkit\u00e4\u00e4n toisella kutsulla. N\u00e4in sek\u00e4 finland ja sweden tulevat valituiksi. Jos komentoriviparametreiss\u00e4 on &#8211;all optio, se k\u00e4ynnist\u00e4\u00e4 &#8220;ALL&#8221; option joka k\u00e4\u00e4nt\u00e4\u00e4 kaikki &#8220;liput&#8221; vastakkaisiksi.<\/p>\n\n\n\n<p>Rutiini tarkistaa my\u00f6s ett\u00e4 optio on kokonainen sana, eli ett\u00e4 sanan j\u00e4lkeen on v\u00e4lily\u00f6nti, pilkku, kaksoispiste (alun lipunkuva) tai merkkijonon loppu. Samoin merkkijoa pit\u00e4\u00e4 edelt\u00e4\u00e4 merkkijonon alku,  v\u00e4lily\u00f6nti, pilkku tai kaksoispiste.<\/p>\n\n\n\n<p>Varsinaiset objektikohtaiset liput ovat flagids kent\u00e4ss\u00e4. Siin\u00e4 on tilaa jokaiselle lipulle (1 merkki\/lippu, arvot 1\/0, tulostetaan\/ei tulosteta).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_toggleflag(unsigned char *flag)\n{\n  int c, ok;\n  unsigned char *p, *q;\n  \n  if(!strcmp(flag, \"ALL\")) {\n    idsall = !idsall;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      flagids&#91;c] = idsall;\n    }\n    flagidflags = 1; \/\/ display flags\n    ok = 1; \/\/ one flag toggled\n  } else {\n    ok = 0;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      p = strstr(idsflags&#91;c].flags, flag);\n      q = idsflags&#91;c].flags;\n      int fl = strlen(flag);\n      if( p != NULL &amp;&amp; \/\/ string found\n\t  (*(p + fl) == ' ' ||  *(p + fl) == ',' || *(p + fl) == ':' || *(p + fl) == '\\0') &amp;&amp; \/\/ character after string\n\t  ( (p == q) || ( *(p - 1) == ' ' || *(p - 1) == ',' || *(p - 1) == ':' ) ) ) { \/\/ character before string\n\tflagids&#91;c] = !flagids&#91;c];\n\t\/\/fprintf(stderr,\"idsflags&#91;%d].flags %s, toggled, value:%d\\n\", c, idsflags&#91;c].flags, flagids&#91;c]);\n\tfflush(stderr);\n\tflagidflags = 1; \/\/ display flags\n\tok = 1; \/\/ one flag toggled\n      }\n    }\n    \/\/if(ok)\n    \/\/  fprintf(stdout,\"\\n\");\n  }\n  return(ok);\n}\n<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int main(int argc, char *argv&#91;])\n{\n....\n  \/\/\n  \/\/ look thru command line parameters\n  \/\/\n\n  for(c = 1; c &lt; argc; c++) {\n\n    int ok = 1;\n    \n    if(!strncmp(\"-\", argv&#91;c], 1)) {\n....\n      } else if(!strcmp(\"--flags\", argv&#91;c])) { \/\/ not ready\n\n\t\/\/ intentionally left empty\n\t\n      } else if(!strcmp(\"--all\", argv&#91;c])) { \/\/ not ready\n\tif(flagsinit) {\n\t  idsall = 1;\n\t  newressu_toggleflag(\"ALL\");\n\t  flagsinit = 0;\n\t}\n\t\n      } else {\n\tok = 0;\n      }\n\n      unsigned char buffer&#91;32];\n      int ok2 = 0;\n      if(!strncmp(argv&#91;c], \"--\", 2)) {\n\tif(flagsinit) {\n\t  idsall = 0;\n\t  newressu_toggleflag(buffer);\n\t  flagsinit = 0;\n\t}\n\tstrcpy(buffer, argv&#91;c] + 2); \/\/ as is\n\tif(newressu_toggleflag(buffer) == 1)\n\t  ok2 = 1;\n\telse {\n\t  strtolower(buffer); \/\/ all letters lowercase\n\t  if(newressu_toggleflag(buffer) == 1)\n\t    ok2 = 1;\n\t  else {\n\t    buffer&#91;0] = toupper(buffer&#91;0]); \/\/ first letter uppercase\n\t    if(newressu_toggleflag(buffer) == 1)\n\t      ok2 = 1;\n\t    else {\n\t      strtoupper(buffer); \/\/ all letters uppercase\n\t      if(newressu_toggleflag(buffer) == 1)\n\t\tok2 = 1;\n\t    }\n\t  }\n\t}\n      }\n      if( (!flagflags &amp;&amp; ok == 0) ||\n\t  (flagflags &amp;&amp; ok == 0 &amp;&amp; ok2 == 0)) {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    } \/\/ if(!strncmp\n  } \/\/ for(c = 0\n\n  if(flagflags) {\n    int first = 1;\n\n    for(d = 0; d &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); d++) {\n      if(flagids&#91;d] == 1) {\n\tif(first) {\n\t  fprintf(stdout,\"flags: \");\n\t  first = 0;\n\t}\n\tfprintf(stdout,\" %s\",idsflags&#91;d].id);\n      }\n    }\n    \n    if(!first)\n      fprintf(stdout,\"\\n\");\n    \n    digits = \"\ud83c\udde6\ud83c\udde7\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddeb\ud83c\uddec\ud83c\udded\ud83c\uddee\ud83c\uddef\ud83c\uddf0\ud83c\uddf1\ud83c\uddf2\ud83c\uddf3\ud83c\uddf4\ud83c\uddf5\ud83c\uddf6\ud83c\uddf7\ud83c\uddf8\ud83c\uddf9\ud83c\uddfa\ud83c\uddfb\ud83c\uddfc\ud83c\uddfd\ud83c\uddfe\ud83c\uddff\";\n    \/\/digits = \"\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddea\ud83c\uddea\ud83c\uddf1\ud83c\uddfb\ud83c\uddf1\ud83c\uddf9\";\n    \n    charspaces = 0;\n    charwidth = 1;\n    size = 5;\n    type = 0;\n    \n  }\t\t       \n\n....\n    } \/\/ if(!strncmp\n....\n  } \/\/ for(c = 0\n....\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty uusi debukki DEBUG77, joka tulostaa yhteenvedon eri alueiden lipuista: t\u00e4ss\u00e4 listaus sen tulostamasta raportista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>area:FINLAND, finland, \u00e5land, count:2\narea:DENMARK, denmark, FaroeIslands, greenland, count:3\narea:NORDIC, finland, \u00e5land, sweden, norway, denmark, FaroeIslands, iceland, greenland, count:8\narea:BALTIC, estonia, latvia, lithuania, count:3\narea:EU, finland, sweden, denmark, estonia, latvia, lithuania, austria, belgium, bulgaria, croatia, cyprus, czechrepublic, france, germany, Greece, Hungary, Ireland, Italy, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, count:27\narea:EUROPE, finland, sweden, norway, denmark, iceland, estonia, latvia, lithuania, ukraine, albania, albania, Armenia, austria, Azerbaijan, belarus, belgium, bulgaria, croatia, cyprus, czechrepublic, france, Georgia, germany, Greece, Hungary, Ireland, Italy, Vatican, Kazakhstan, Liechtenstein, Luxembourg, Malta, moldova, monaco, montenegro, Netherlands, Poland, Portugal, Romania, Russia, sanmarino, serbia, Slovakia, Slovenia, Turkey, Spain, UnitedKingdom, count:47\narea:ASIA, Armenia, Azerbaijan, cyprus, Georgia, Kazakhstan, Russia, Turkey, UnitedArabEmirates, Afghanistan, Bangladesh, Bahrain, Brunei, Bhutan, China, HongKong, Indonesia, Israel, India, Iraq, Iran, Jordan, Japan, Kyrgyzstan, Cambodia, SouthKorea, Kuwait, Laos, Lebanon, SriLanka, Mongolia, Macao, Maldives, Myanmar, Malaysia, NorthKorea, Nepal, Oman, Philippines, Pakistan, Palestine, Qatar, SaudiArabia, Singapore, Syria, Thailand, Tajikistan, EastTimor, Turkmenistan, Taiwan, Uzbekistan, Vietnam, Yemen, Egypt, count:53\narea:AFRICA, Nigeria, Ethiopia, Eritrea, Congo, DemocraticCongo, Tanzania, SouthAfrica, Kenya, Uganda, SouthSudan, sudan, Algeria, Egypt, Libya, Madeira, Morocco, Angola, Ghana, Mozambique, Madagascar, mayotte, IvoryCoast, Cameroon, Niger, BurkinaFaso, Mali, Malawi, Zambia, Chad, Somalia, Senegal, Zimbabwe, Guinea, Rwanda, Benin, Burundi, Tunisia, Togo, SierraLeone, Congo, Liberia, Mauritania, Eritrea, Gambia, Botswana, Namibia, Gabon, Lesotho, GuineaBissau, Mauritius, Mozambique, Eswatini, Djibouti, Comoros, CapeVerde, WesternSahara, Seychelles, R\u00e9union, count:58\narea:NORTHAFRICA, Algeria, Egypt, Libya, Madeira, Morocco, Tunisia, WesternSahara, count:7\narea:EASTAFRICA, Ethiopia, Eritrea, Tanzania, Kenya, Uganda, SouthSudan, sudan, Madagascar, mayotte, Malawi, Zambia, Somalia, Zimbabwe, Rwanda, Burundi, Eritrea, Mauritius, Mozambique, Djibouti, Seychelles, R\u00e9union, count:21\narea:CENTRALAFRICA, Congo, DemocraticCongo, Angola, Cameroon, Chad, CentralAfrican, Gabon, EquatorialGuinea, S\u00e3oTom\u00e9andPr\u00edncipe, count:9\narea:SOUTHAFRICA, SouthAfrica, Botswana, Namibia, Lesotho, Eswatini, count:5\narea:WESTAFRICA, Ghana, IvoryCoast, Niger, BurkinaFaso, Mali, Senegal, Guinea, Benin, Togo, SierraLeone, Liberia, Mauritania, Gambia, GuineaBissau, CapeVerde, count:15\narea:SOUTHAMERICA, Argentina, Bolivia, Brazil, Chile, Colombia, Ecuador, FalklandIslands, FrenchGuiana, Guyana, Paraguay, Peru, Suriname, Uruguay, Venezuela, count:14\narea:NORTHAMERICA, greenland, Anguilla, AntiguaAndBarbuda, Aruba, Bahamas, Barbados, Belize, Bermuda, Bonaire, BritishVirginIslands, Canada, CaymanIslands, ClippertonIsland, CostaRica, Cuba, Cura\u00e7ao, Dominica, DominicanRepublic, ElSalvador, Greenland, Grenada, Guadeloupe, Guatemala, Haiti, Honduras, Jamaica, Martinique, Mexico, Montserrat, Nicaragua, Panama, PuertoRico, Saba, SaintBarth\u00e9lemy, SaintKitts, SaintLucia, SaintMartin, SaintPierre, SaintVincent, TrinidadandTobago, VirginIslands, count:41\narea:OCEANIA, kiribati, count:1\narea:ALL, finland, \u00e5land, sweden, norway, denmark, FaroeIslands, iceland, greenland, estonia, latvia, lithuania, ukraine, albania, albania, Armenia, austria, Azerbaijan, belarus, belgium, bosniaandherzegovina, bulgaria, croatia, cyprus, czechrepublic, france, Georgia, germany, Greece, Hungary, Ireland, Italy, Vatican, Kazakhstan, Liechtenstein, Luxembourg, Malta, moldova, monaco, montenegro, Netherlands, northmacedonia, Poland, Portugal, Romania, Russia, sanmarino, serbia, Slovakia, Slovenia, Turkey, Spain, UnitedKingdom, England, Scotland, Wales, Anguilla, AntiguaAndBarbuda, Argentina, Aruba, Bahamas, Barbados, Belize, Bermuda, Bolivia, Bonaire, BouvetIsland, Brazil, BritishVirginIslands, Canada, CaymanIslands, Chile, ClippertonIsland, Colombia, CostaRica, Cuba, Cura\u00e7ao, Dominica, DominicanRepublic, Ecuador, ElSalvador, FalklandIslands, FrenchGuiana, Greenland, Grenada, Guadeloupe, Guatemala, Guyana, Haiti, Honduras, Jamaica, Martinique, Mexico, Montserrat, Navassa, Nicaragua, Panama, Paraguay, Peru, PuertoRico, Saba, SaintBarth\u00e9lemy, SaintKitts, SaintLucia, SaintMartin, SaintPierre, SaintVincent, SintMaarten, SouthGeorgia, Suriname, TrinidadandTobago, TurksandCaicos, UnitedStatesofAmerica, VirginIslands, Uruguay, Venezuela, UnitedArabEmirates, Afghanistan, Bangladesh, Bahrain, Brunei, Bhutan, China, HongKong, Indonesia, Israel, India, Iraq, Iran, Jordan, Japan, Kyrgyzstan, Cambodia, SouthKorea, Kuwait, Laos, Lebanon, SriLanka, Mongolia, Macao, Maldives, Myanmar, Malaysia, NorthKorea, Nepal, Oman, Philippines, Pakistan, Palestine, Qatar, SaudiArabia, Singapore, Syria, Thailand, Tajikistan, EastTimor, Turkmenistan, Taiwan, Uzbekistan, Vietnam, Yemen, Nigeria, Ethiopia, Eritrea, Congo, DemocraticCongo, Tanzania, SouthAfrica, Kenya, Uganda, SouthSudan, sudan, Algeria, Egypt, Libya, Madeira, Morocco, Angola, Ghana, Mozambique, Madagascar, mayotte, IvoryCoast, Cameroon, Niger, BurkinaFaso, Mali, Malawi, Zambia, Chad, Somalia, Senegal, Zimbabwe, Guinea, Rwanda, Benin, Burundi, Tunisia, Togo, SierraLeone, Congo, CentralAfrican, Liberia, Mauritania, Eritrea, Gambia, Botswana, Namibia, Gabon, Lesotho, GuineaBissau, EquatorialGuinea, Mauritius, Mozambique, Eswatini, Djibouti, Comoros, CapeVerde, WesternSahara, S\u00e3oTom\u00e9andPr\u00edncipe, Seychelles, Australia, kiribati, antarctica, cookislands, newzealand, niue, tokelau, americansamoa, britishindianocean, christmasisland, cocosislands, fiji, frenchpolynesia, frenchsouthernandantarctic, gibraltar, guam, guernsey, heardandmacdonaldsislands, manisle, jersey, liechtenstein, marshallislands, micronesia, nauru, newcaledonia, norfolkisland, northernmariana, paiau, papuanewguinea, pitcairn, R\u00e9union, tristandacunha, samoa, solomonislands, janmayen, tuvalu, usminoroutlyingislands, vanuatu, wallisandfutuna, count:259\n00000 23933476602239466377815183666336410526913255853507880902531575913\n00001 75892311131489151051584635035296694319912096485236112089206322461\n00002 38592554073360093998514241158337970540330801205676600268884077746\n00003 13319205731345237480638193592296597610207468715353376895830326942\n00004 35590860392770168574790082985573286375551823885389108732528064216\n00005 25219754152834136322488110178605362616714455236854036050793549832\n00006 45176182884339628322847596264906590850829829071656985062184052439\n00007 51278261352573525446779932273640595147314743083454039849513229535\n00008 44658224189508110992349860032329909065106543682283883425608435040\n00009 48669205961987714566615256512928279472410821451443832019885646062<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 77-debukin koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG77\n\n#ifdef DEBUG77\n\n  unsigned char *areaflags = \"FINLAND, DENMARK, NORDIC, BALTIC, EU, EUROPE, ASIA, AFRICA, SOUTHAMERICA, NORTHAMERICA, OCEANIA, ALL\", *a;\n  unsigned char name&#91;1024];\n  \n  a = areaflags;\n  while(*a != '\\0' &amp;&amp; newressu_get_name(sizeof(name), name, &amp;a)) {\n    fprintf(stdout,\"area: %s\",name);\n    count = 0;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      if(!strcmp(name, \"ALL\")) {\n\tcount++;\n\tq = idsflags&#91;c].flags;\n\tunsigned char name2&#91;1024];\n\tnewressu_get_name(sizeof(name2), name2, &amp;q);\n\tnewressu_get_name(sizeof(name2), name2, &amp;q);\n\tnewressu_get_name(sizeof(name2), name2, &amp;q);\n\tnewressu_get_name(sizeof(name2), name2, &amp;q);\n\tfprintf(stdout,\", %s\",name2);\n      } else {\t\n\tp = strstr(idsflags&#91;c].flags, name);\n\tq = idsflags&#91;c].flags;\n\tint fl = strlen(name);\n\tif( p != NULL &amp;&amp; \/\/ string found\n\t    ( isblank(*(p + fl)) || ispunct(*(p + fl)) || *(p + fl) == '\\0' ) &amp;&amp; \/\/ character after string\n\t    ( (p == q) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) { \/\/ character before string\n\t  count++;\n\t  q = idsflags&#91;c].flags;\n\t  unsigned char name2&#91;1024];\n\t  newressu_get_name(sizeof(name2), name2, &amp;q);\n\t  newressu_get_name(sizeof(name2), name2, &amp;q);\n\t  newressu_get_name(sizeof(name2), name2, &amp;q);\n\t  newressu_get_name(sizeof(name2), name2, &amp;q);\n\t  fprintf(stdout,\", %s\",name2);\n\t}\n      }\n    }\n    fprintf(stdout,\", count:%d\",count);\n    fprintf(stdout,\"\\n\");\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Edellisen debukin k\u00e4ytt\u00e4m\u00e4 get_name rutiini:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_get_name(int length, unsigned char *name, unsigned char **p2)\n{\n  int len, ok = 0;\n  unsigned char *n, *p;\n\n  p = *p2;\n  n = name;\n  len = 0;\n  \n  while(ispunct(*p) || isblank(*p)) {\n    p++;\n  }\n\n  while(*p != '\\0' &amp;&amp; !ispunct(*p) &amp;&amp; !isblank(*p)) {\n    if(len &lt; length) {\n      *n++ = *p;\n      ok = 1;\n    }\n    p++;\n    len++;\n  }\n  *n = '\\0';\n  \n  *p2 = p;\n\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty terttuutil1:een uusi tapa tuottaa testimateriaalia. T\u00e4ss\u00e4 testimateriaalia luodaan edelt\u00e4 m\u00e4\u00e4ritellyn rakenteen mukaisesti: rakenteessa luetellaan kent\u00e4t, joita tarvitaan ja niiden arvojoukot ja tulostuksen formatointi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    struct field {\n      unsigned char *fieldname;\n      int fieldtype;\n      int lowlimit;\n      int highlimit;\n      unsigned char *valuestring;\n    } fields&#91;] = {\n      { \"asno\", SEQUENTIAL, 0, 0,\"10%05d\" },\n      { \"asnimi\", SEQUENTIAL, 0,0, \"nimi: %d\" },\n      { \"asoso\", SEQUENTIAL, 0, 0, \"osoite: %d\" },\n      { \"aspono\", RANDOM, 0, 99999, \"postinumero%d\"},\n      { \"aspotmp\", RANDOM, 0, 50, \"postitmp %d\"},\n      { \"asry\", RANDOM, 0, 10, \"1%d\"},\n      { \"asmail\", RANDOM, 0, 10, \"mail: %d\"},\n    };<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 p\u00e4tk\u00e4 edellisen mukaan luotua testimateriaalia: T\u00e4ss\u00e4 on testailun helpottamiseksi k\u00e4ytetty lyhyempi\u00e4 kenttien nimi\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'asno' = \"1000000\", 'asnimi' = \"nimi: 0\", 'asoso' = \"osoite: 0\", 'aspono' = \"postinumero54863\", 'aspotmp' = \"postitmp 20\", 'asry' = \"10\", 'asmail' = \"mail: 7\"\n'asno' = \"1000001\", 'asnimi' = \"nimi: 1\", 'asoso' = \"osoite: 1\", 'aspono' = \"postinumero58039\", 'aspotmp' = \"postitmp 25\", 'asry' = \"13\", 'asmail' = \"mail: 8\"\n'asno' = \"1000002\", 'asnimi' = \"nimi: 2\", 'asoso' = \"osoite: 2\", 'aspono' = \"postinumero53052\", 'aspotmp' = \"postitmp 44\", 'asry' = \"15\", 'asmail' = \"mail: 2\"\n'asno' = \"1000003\", 'asnimi' = \"nimi: 3\", 'asoso' = \"osoite: 3\", 'aspono' = \"postinumero49398\", 'aspotmp' = \"postitmp 22\", 'asry' = \"12\", 'asmail' = \"mail: 2\"\n'asno' = \"1000004\", 'asnimi' = \"nimi: 4\", 'asoso' = \"osoite: 4\", 'aspono' = \"postinumero73740\", 'aspotmp' = \"postitmp 7\", 'asry' = \"17\", 'asmail' = \"mail: 3\"<\/code><\/pre>\n\n\n\n<p>Ja koodi, jolla materiaali luodaan: T\u00e4ss\u00e4 on kenttien arvojen tekemiseen k\u00e4ytetty aiempaa stream_cipher rutiinia: stream_open() ja stream_bytes(). N\u00e4in on saatu data-arvot pysym\u00e4\u00e4n samoina, jos vain kenttien m\u00e4\u00e4r\u00e4 ja kenttien arvot pysyv\u00e4t samoina.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  if(test2flag) {\n#define SEQUENTIAL 1\n#define RANDOM 2\n    \n    struct field {\n      unsigned char *fieldname;\n      int fieldtype;\n      int lowlimit;\n      int highlimit;\n      unsigned char *valuestring;\n    } fields&#91;] = {\n      { \"asno\", SEQUENTIAL, 0, 0,\"10%05d\" },\n      { \"asnimi\", SEQUENTIAL, 0,0, \"nimi: %d\" },\n      { \"asoso\", SEQUENTIAL, 0, 0, \"osoite: %d\" },\n      { \"aspono\", RANDOM, 0, 99999, \"postinumero%d\"},\n      { \"aspotmp\", RANDOM, 0, 50, \"postitmp %d\"},\n      { \"asry\", RANDOM, 0, 10, \"1%d\"},\n      { \"asmail\", RANDOM, 0, 10, \"mail: %d\"},\n    };\n\n    stream_open(0, \"kalakala\");\n    \n    for(c = 0; c &lt; TEST_SETS; c++) {\n      if(quitcmd)\n\tbreak;\n\n      first = 1;\n\n      for(d = 0; d &lt; sizeof(fields) \/ sizeof(fields&#91;0]); d++) {\n\tif(!first)\n\t  more_printf(stdout,\", \");\n\tmore_printf(stdout,\"'%s'\", fields&#91;d].fieldname);\n\tmore_printf(stdout,\" = \");\n\tmore_printf(stdout,\"\\\"\");\n\tif(fields&#91;d].fieldtype = RANDOM &amp;&amp; (fields&#91;d].lowlimit != 0 || fields&#91;d].highlimit != 0)) {\n\t  unsigned int e = stream_gen_limit(fields&#91;d].highlimit - fields&#91;d].lowlimit) + fields&#91;d].lowlimit;\n\t  more_printf(stdout, fields&#91;d].valuestring, e);\n\t} else {\n\t  more_printf(stdout, fields&#91;d].valuestring, c);\n\t}\n\tmore_printf(stdout,\"\\\"\");\n\tfirst = 0;\n      }\n      more_printf(stdout,\"\\n\");\n    }\n    more_printf(stdout,\"\\n\");\n  }<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 aiemmin k\u00e4ytetty stream_gen_limit() rutiini:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned long stream_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) { \/\/ one byte\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n\n    } else if(limit &lt;= 0x10000) { \/\/ two bytes\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n\n    } else if(limit &lt;= 0x1000000) { \/\/ three bytes\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n\n    } else if(limit &lt;= 0x100000000) { \/\/ four bytes\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n\n    } else if(limit &lt;= 0x10000000000) { \/\/ five bytes\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n\n    } else if(limit &lt;= 0x1000000000000) { \/\/ six bytes\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n\n    } else if(limit &lt;= 0x100000000000000) { \/\/ seven bytes\n      highlimit = (0x100000000000000 \/ limit) * limit;      \n      bytes = 7;\n\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | stream_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n  return(word);\n}\n<\/code><\/pre>\n\n\n\n<p>Ja -_limit rutiinissa k\u00e4ytetty stream_genbyte():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int stream_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    gent_clear();\n    stream_bytes(sizeof(gent), gent);\n  } \/\/ if(gent_pos==0\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n  return(ch);\n}<\/code><\/pre>\n\n\n\n<p>Ja kaikki stream cipher rutiinit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n\n}\n\nstatic int streamt_pos = 0;\n\nvoid stream_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n      stream_internalbytes(streamt); \/\/ read next random bytes\n\n      stream_internalbytes(stream_key); \/\/ change key\n\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n\n  } \/\/ end of for(c = 0; c &lt; size; c++)\n}\n\n#define STREAM_KEY_ROUNDS 1024 \/\/ should be fast enough and slow enough, now 1024\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n\n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n    HashFinal(stream_key, &amp;hash);\n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#define DEBUG21 2\n\n#ifdef DEBUG21\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" randomness from key, key=\");\n  dumpbin(stderr, size, key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n  \n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}<\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 stream_cipher:in k\u00e4ytt\u00e4m\u00e4t cvar rutiinit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n\n#ifdef DEBUG20\n  ressu_dump(\"cvar\", cvarsize + 1, cvar, 32);\n#endif\n}\n\n#define aCVARRANDOMSTART 2 \/\/ off by default\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n  \n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n#ifdef CVARRANDOMSTART\n  ressu_genbytes(8, (unsigned char *)&amp;cvar);  \n#endif\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}<\/code><\/pre>\n\n\n\n<p>Koko koodi terttuutil1:een oli aiemmin artikkelissa.<\/p>\n\n\n\n<p>Aiemmin artikkelissa sanoin, ett\u00e4 ressu on one time pad materiaalia, ja sill\u00e4 perusteella kirjoitinkin ohjelman, jolla voi luoda uniikkia one time pad materiaalia, jos numeeristen tietokenttien pit\u00e4\u00e4 olla uniikkeja. T\u00e4ss\u00e4 p\u00e4tk\u00e4 mallitiedostosta: en kerro t\u00e4ss\u00e4 miten materiaalia k\u00e4ytet\u00e4\u00e4n, mutta youtube:ssa on videoita aiheesta (hakusana one time pad).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressuonetimepad\n00000  22983 29088 27522 06071 83152 08423 04809 75707 72840 83759\n00001  86262 02471 71623 56655 70705 45228 74332 59496 49090 79319\n00002  87718 95655 33822 66347 41853 60517 65396 19485 13898 95025\n00003  80611 58219 13708 85033 79649 76119 20896 26169 59084 38831\n00004  18935 82852 05160 52485 01070 62471 51691 27036 56925 84451\n00005  81595 77010 72735 56554 46639 59640 98532 50613 19521 75984\n00006  58259 83748 30984 76252 81888 50448 59479 95014 43388 53501\n00007  27187 69156 44641 13931 53178 46699 73574 26870 61794 93634\n00008  45352 47203 46311 69134 03390 76745 88596 56731 59709 76978\n00009  52048 41207 13038 04123 02288 20990 29157 44586 14704 11880\nCtrl-c\n$<\/code><\/pre>\n\n\n\n<p>Ja pieni ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;memory.h&gt;\n\nunsigned char *procname = NULL;\nstatic unsigned char *programname = \"newressuonetimepad version 0.02 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2013-2024 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define GENT_SIZE 128\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\n#define USE_PSEUDORESSU 2\n\nvoid ressu_genbytes(int size, unsigned char *buffer);\n#ifdef USE_PSEUDORESSU\nvoid pseudoressu_bytes(int size, unsigned char *buffer);\nvoid ressutwist_bytes(int size, unsigned char *buffer);\n#endif\n\n#define INPUT_RESSU 0\n#define INPUT_RESSUTWIST 2\n\nint input = INPUT_RESSU;\n\nint newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n    if(input == INPUT_RESSU)\n      ressu_genbytes(sizeof(gent), gent);\n    else if(input == INPUT_RESSUTWIST)\n      ressutwist_bytes(sizeof(gent), gent);\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\nunsigned long newressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n  return(word);\n}\n\n#define CODECHARS 5\n#define CODES 100000\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, e, f, help = 0, mode = 1;\n  int data&#91;CODES];\n\n  procname = argv&#91;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\n      if(!strcmp(\"--help\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--ressu\", argv&#91;c])) {\n\tinput = INPUT_RESSU;\n\n      } else if(!strcmp(\"--ressutwist\", argv&#91;c]) \/\/ JariK 2023\n\t\t|| !strcmp(\"--ressuwtwist\", argv&#91;c])\n\t        || !strcmp(\"--twist\", argv&#91;c]) ) {\n\tinput = INPUT_RESSUTWIST;\n\n      } else if(!strcmp(\"--mode1\", argv&#91;c])) {\n\tmode = 1;\n\t\n      } else if(!strcmp(\"--mode2\", argv&#91;c])) {\n\tmode = 2;\n\n      } else if(!strcmp(\"--mode3\", argv&#91;c])) {\n\tmode = 3;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    }\n  } \/\/ end of for(c = 1; c &lt; argc; c++)\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--mode1]\");\n    fprintf(stderr,\" &#91;--mode2]\");\n    fprintf(stderr,\" &#91;--mode3]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  fprintf(stdout,\"mode:%d\", mode);\n  fprintf(stdout,\", input:%d\", input);\n  fprintf(stdout,\"\\n\");\n  if(mode == 1) { \/\/ simple, not unique. you can also use .\/newressu --otp5n -w10\n\n    for(c = 0; c &lt; CODES; c++) {\n      data&#91;c] = newressu_gen_limit(CODES);\n    }\n\n  } else if(mode == 2) { \/\/ unique faster\n\n    for(c = 0; c &lt; CODES; c++) {\n      data&#91;c] = c;\n    }\n    \n    for(c = 0; c &lt; CODES; c++) {\n      e = newressu_gen_limit(CODES);\n      f = data&#91;e];\n      data&#91;e] = data&#91;c];\n      data&#91;c] = f;\n    }\n\n  } else if (mode == 3) { \/\/ unique slower\n\n    for(c = 0; c &lt; CODES; c++) {\n      int ok = 0;\n      while(!ok) {\n\te = newressu_gen_limit(CODES);\n\tok = 1;\n\tfor(d = 0; d &lt; c; d++) {\n\t  if(data&#91;d] == e) {\n\t    ok = 0;\n\t    break;\n\t  }\n\t}\n      }\n      data&#91;c] = e;\n    }  \n  }\n\n  int lineno = 0;\n\n  for(c = 0; c &lt; CODES; c++) {\n    if(c % 10 == 0) {\n      if(c &gt; 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%05d \", lineno);\n      lineno++;\n    }\n    fprintf(stdout,\" %0*d\", CODECHARS, data&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n\n  exit(0);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty lippuihin australasia, melanesia, micronesia ja polynesia. Yksinkertaistettu lippufunktioita ja lis\u00e4tty DEBUG77:an kaksimerkkinen iso koodi maan nimen per\u00e4\u00e4n: t\u00e4ss\u00e4 DEBUG77 muutokset:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG77\n\n#ifdef DEBUG77\n\n  unsigned char *areaflags = \"FINLAND, DENMARK, NORDIC, BALTIC, EU, EUROPE, ASIA, AFRICA, NORTHAFRICA, EASTAFRICA, CENTRALAFRICA, SOUTHAFRICA, WESTAFRICA SOUTHAMERICA, NORTHAMERICA, OCEANIA, AUSTRALASIA, MELANESIA, MICRONESIA, POLYNESIA, ALL\", *a;\n  unsigned char name&#91;128];\n  \n  a = areaflags;\n  while(*a != '\\0' &amp;&amp; newressu_getname(sizeof(name), name, &amp;a)) {\n    fprintf(stdout,\"area:%s\",name);\n    int count = 0;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      if(!strcmp(name, \"ALL\")) {\n\tcount++;\n\tunsigned char *q = idsflags&#91;c].flags;\n\tunsigned char name2&#91;128], name3&#91;128];\n\tnewressu_getname(sizeof(name2), name2, &amp;q); \/\/ flag\n\tnewressu_getname(sizeof(name2), name2, &amp;q); \/\/ 2 char isocode\n\tnewressu_getname(sizeof(name3), name3, &amp;q); \/\/ 3 char isocode\n\tnewressu_getname(sizeof(name3), name3, &amp;q); \/\/ name\n\tfprintf(stdout,\", %s(%s)\",name3, name2); \/\/ name and isocode2 needed\n      } else {\t\n\n\tif(newressu_strstr(idsflags&#91;c].flags, name)!=NULL) {\n\t  count++;\n\t  unsigned char *q = idsflags&#91;c].flags;\n\t  unsigned char name2&#91;128], name3&#91;128];\n\t  newressu_getname(sizeof(name2), name2, &amp;q); \/\/ flag\n\t  newressu_getname(sizeof(name2), name2, &amp;q); \/\/ 2 char isocode\n\t  newressu_getname(sizeof(name3), name3, &amp;q); \/\/ 3 char isocode\n\t  newressu_getname(sizeof(name3), name3, &amp;q); \/\/ name\n\t  fprintf(stdout,\", %s(%s)\", name3, name2); \/\/ name and isocode2 needed\n\t}\n      }\n    }\n    fprintf(stdout,\", count:%d\",count);\n    fprintf(stdout,\"\\n\");\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 getname funktio:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_getname(int length, unsigned char *name, unsigned char **p2)\n{\n  int len, ok = 0;\n  unsigned char *n, *p;\n\n  p = *p2;\n  n = name;\n  len = 0;\n  \n  while(ispunct(*p) || isblank(*p)) {\n    p++;\n  }\n\n  while(*p != '\\0' &amp;&amp; !ispunct(*p) &amp;&amp; !isblank(*p)) {\n    if(len &lt; length) {\n      *n++ = *p;\n      ok = 1;\n    }\n    p++;\n    len++;\n  }\n  *n = '\\0';\n  \n  *p2 = p;\n\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>Ja uusi newressu_strstr funktio: standardiin funktioon on lis\u00e4tty se, ett\u00e4 etsitt\u00e4v\u00e4n merkkijonon pit\u00e4\u00e4 alkaa ja loppua sanarajalla.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)\n{\n  int fl;\n  unsigned char *p = haystack;\n\n  while(*p != '\\0') {\n    fl = strlen(needle);\n    if(!strncmp(p, needle, strlen(needle)) &amp;&amp;\n       ( isblank(*(p + fl)) || ispunct(*(p + fl)) || *(p + fl) == '\\0' ) &amp;&amp; \/\/ character after string\n       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) { \/\/ character before string\n      return(p);\n    }\n    p++;\n  }\n  return(NULL);\n}<\/code><\/pre>\n\n\n\n<p>Olen aiemmin sanonut ett\u00e4 satunnaislukujen luomiseen kannattaa k\u00e4ytt\u00e4\u00e4 useampia satunnaisbittigeneraattoreita summattuna. T\u00e4ss\u00e4 uusi satunnaislukul\u00e4hde ressutwist (Ressu with twist), jossa ressuun lis\u00e4t\u00e4\u00e4n pseudoressu. Molemmat vaikuttavat olevan hyvi\u00e4 generaattoreita, ja niiden yhdiste olisi tietenkin vaikeampi murtaa.<\/p>\n\n\n\n<p>Seuraavassa twistin koodi: Aluksi koodi newressu_genbyte:st\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n#ifdef DEBUG23\n    ressu_dump(\"oldgent\", 32, gent, 32); \/\/ first 32 bytes\n#endif\n\n    gent_clear();\n    \n    if(input == INPUT_RESSU) \/\/ ressu prod\n      ressu_genbytes(sizeof(gent), gent);\n\n#ifdef SHA256\n    else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n      pseudoressu_bytes(sizeof(gent), gent);\n    \n#endif\n#ifdef SHA256\n    else if(input == INPUT_RESSUTWIST) {\/\/ ressu w twist\n      ressu_genbytes(sizeof(gent), gent);\n      pseudoressu_bytes(sizeof(gent), gent);\n    }\n#endif\n    else if(input == INPUT_FASTRESSU) \/\/ ressu_fast\n      ressu_genbytes_fast(sizeof(gent), gent);\n\n    else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n      ressu_genbytes_single(sizeof(gent), gent);\n\n<\/code><\/pre>\n\n\n\n<p>Koodi sample():sta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      \/\/memset(buffer, 0, blocksize);\n      \n      if(input == INPUT_RESSU) \/\/ ressu prod\n\tressu_genbytes(blocksize, buffer);\n      \n      else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n\tpseudoressu_bytes(blocksize, buffer);\n      \n      else if(input == INPUT_RESSUTWIST) { \/\/ ressu w twist\n\tressu_genbytes(blocksize, buffer);\n\tpseudoressu_bytes(blocksize, buffer);\n      \n      } else if(input == INPUT_FASTRESSU) \/\/ ressu fast\n\tressu_genbytes_fast(blocksize, buffer);\n      \n      else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n\tressu_genbytes_single(blocksize, buffer);\n     <\/code><\/pre>\n\n\n\n<p>Koodi komentoparametrien k\u00e4sittelyst\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--ressu\", argv&#91;c])) {\n\tinput = INPUT_RESSU;\n\n      } else if(!strcmp(\"--pseudoressu\", argv&#91;c])) {\n\tinput = INPUT_PSEUDORESSU;\n\n      } else if(!strcmp(\"--ressutwist\", argv&#91;c]) \/\/ JariK 2023\n\t\t|| !strcmp(\"--ressuwtwist\", argv&#91;c])\n\t        || !strcmp(\"--twist\", argv&#91;c]) ) {\n\tinput = INPUT_RESSUTWIST;\n\n      } else if(!strcmp(\"--fast\", argv&#91;c])\n\t\t|| !strcmp(\"--fastressu\", argv&#91;c]) ) {\n\tinput = INPUT_FASTRESSU;\n\n      } else if(!strcmp(\"--single\", argv&#91;c])\n\t\t|| !strcmp(\"--singleressu\", argv&#91;c]) ) {\n\tinput = INPUT_SINGLERESSU;<\/code><\/pre>\n\n\n\n<p>Jos ajatteluni pit\u00e4\u00e4 paikkansa twist:in pit\u00e4isi my\u00f6s olla one time pad kelpoinen. Siin\u00e4 on siis ressu, joka on one time pad kelpoinen ja kun one time pad kelpoisiin bitteihin lis\u00e4t\u00e4\u00e4n joku muu satunnaisgeneraattori (t\u00e4ss\u00e4 pseudoressu), se on viel\u00e4kin one time pad kelpoinen.<\/p>\n\n\n\n<p>Sitten ns &#8220;bad for randomness&#8221; -korjaus: Alkuper\u00e4inen eli viallinen koodi on merkitty #ifdef OLD1 iffeill\u00e4 ja korjattu koodi on kaksi rivi\u00e4 ennen niit\u00e4. Alkuper\u00e4isen\u00e4 ajatuksena oli satunnaistaa kehitetyn satunnaispuskurin merkkien j\u00e4rjestyst\u00e4 lis\u00e4\u00e4, mutta se todellisuudessa v\u00e4hent\u00e4\u00e4 sit\u00e4. Luulisin ett\u00e4 ongelma johtuu siit\u00e4 ett\u00e4 todellisuudessa vanhoilla koodiriveill\u00e4 samoista merkeist\u00e4 kopioidaan vain osa ja niit\u00e4kin eri m\u00e4\u00e4r\u00e4. Yht\u00e4 merkki\u00e4 kopioidaan kolme kertaa, seuraavaa kaksi, seuraavaa yksi ja seuraavaa ei kopioida ollenkaan. Alkuper\u00e4inen idea vanhoilla riveill\u00e4 oli, ett\u00e4 kun valitaan seuraavista 256 merkist\u00e4 satunnainen, niin se sis\u00e4lt\u00e4\u00e4 keskim\u00e4\u00e4rin kaikki vaihtoehdot 0-255.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n---\n    } \/\/ if(ressut_pos == 0)\n    buffer&#91;c] ^= ressut&#91;ressut_pos];\n    ressut_pos = (ressut_pos + 1) % ressut_bytes;\n#ifdef OLD1\n    ressut_f = (ressut_f + ressut&#91;ressut_pos] + 2) % ressut_bytes; \/\/ bad for randomness... JariK 2023\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos + 1) % ressut_bytes;\n#endif\n  } \/\/ for(c = 0; c &lt; size; c++)\n...\n}<\/code><\/pre>\n\n\n\n<p>&#8220;bad for randomness&#8221; bugin esittely\u00e4 varten tein sample() ajoista seuraavan kaltaisen, terttu tyylisen raportin: Raportilla satunnaisuuden l\u00e4hde, tiedoston koko, tiedoston nimi, WEAK-rivit ja FAILED-rivit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'input' = \"pseudoressu\", 'filesize' = \"1080m\", 'filename' = \"newressusample801.rnd\", 'weak' = \"5\", 'failed' = \"3\"\n'input' = \"pseudoressu\", 'filesize' = \"1g\", 'filename' = \"newressusample802.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"urandom\", 'filesize' = \"1g200m\", 'filename' = \"newressusample836.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g200m\", 'filename' = \"newressusample837.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"twist\", 'filesize' = \"1g200m\", 'filename' = \"newressusample838.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"ressubfr1\", 'filesize' = \"10g\", 'filename' = \"newressusample897.rnd\", 'weak' = \"12\", 'failed' = \"31\"\n'input' = \"ressubfr1\", 'filesize' = \"20g\", 'filename' = \"newressusample832.rnd\", 'weak' = \"8\", 'failed' = \"34\"\n'input' = \"ressubfr1\", 'filesize' = \"30g\", 'filename' = \"newressusample860.rnd\", 'weak' = \"9\", 'failed' = \"33\"<\/code><\/pre>\n\n\n\n<p>Raportin koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dump_sample() \/\/ &amp; dieharder analysis\n{\n...\n    FILE *fp2;\n    if((fp2 = fopen(\"newressudieharder.skk\", \"a\")) != NULL) { \/\/\n      fprintf(fp2,\"'input' = \\\"%s\\\"\", input_str);\n      if(filesize_str != NULL)\n\tfprintf(fp2,\", 'filesize' = \\\"%s\\\"\", filesize_str);\n      if(blocksize_str != NULL)\n\tfprintf(fp2,\", 'blocksize' = \\\"%s\\\"\", blocksize_str);\n      if(blocks_str != NULL)\n\tfprintf(fp2,\"'blocks' = \\\"%s\\\"\", blocks_str);\n      fprintf(fp2,\", 'filename' = \\\"%s\\\"\", filename);\n      fprintf(fp2,\", 'weak' = \\\"%lld\\\"\", weak);\n      fprintf(fp2,\", 'failed' = \\\"%lld\\\"\", failed);\n      fprintf(fp2,\"\\n\");\n      fclose(fp2);\n    }\n...\n}<\/code><\/pre>\n\n\n\n<p>Ajoin &#8211;sample &#8211;dieharder rutiinia seuraavankaltaisilla shellscript:eill\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat newressidieharder7.sh\n#!\/bin\/bash -x\n.\/newressu --sample --dieharder --filesize 500m $@\n.\/newressu --sample --dieharder --filesize 600m $@\n.\/newressu --sample --dieharder --filesize 700m $@\n.\/newressu --sample --dieharder --filesize 800m $@\n.\/newressu --sample --dieharder --filesize 900m $@\n.\/newressu --sample --dieharder --filesize 1g $@\n.\/newressu --sample --dieharder --filesize 1g100m $@\n.\/newressu --sample --dieharder --filesize 1g200m $@\n.\/newressu --sample --dieharder --filesize 1g300m $@\n.\/newressu --sample --dieharder --filesize 1g400m $@\n.\/newressu --sample --dieharder --filesize 1g500m $@\n.\/newressu --sample --dieharder --filesize 1g600m $@\n.\/newressu --sample --dieharder --filesize 1g700m $@\n.\/newressu --sample --dieharder --filesize 1g800m $@\n.\/newressu --sample --dieharder --filesize 1g900m $@\n.\/newressu --sample --dieharder --filesize 2g $@\n.\/newressu --sample --dieharder --filesize 3g $@\n.\/newressu --sample --dieharder --filesize 4g $@\n.\/newressu --sample --dieharder --filesize 5g $@\n.\/newressu --sample --dieharder --filesize 6g $@\n$ chmod +x newressudieharder7.sh\n$ .\/newressudieharder7.sh --single\n....<\/code><\/pre>\n\n\n\n<p>Single riveill\u00e4 raportti n\u00e4ytt\u00e4\u00e4 hyv\u00e4lt\u00e4: failed rivej\u00e4 on vain alle 1g tiedostoissa ja weak rivej\u00e4 on vain muutamia tiedoston koosta huolimatta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep single newressudieharder7.sh\n'input' = \"single\", 'filesize' = \"1g\", 'filename' = \"newressusample913.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1028.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g200m\", 'filename' = \"newressusample914.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g300m\", 'filename' = \"newressusample915.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g400m\", 'filename' = \"newressusample916.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g500m\", 'filename' = \"newressusample917.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g600m\", 'filename' = \"newressusample918.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g700m\", 'filename' = \"newressusample919.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"10g\", 'filename' = \"newressusample921.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"500m\", 'filename' = \"newressusample1022.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"single\", 'filesize' = \"600m\", 'filename' = \"newressusample1023.rnd\", 'weak' = \"7\", 'failed' = \"1\"\n'input' = \"single\", 'filesize' = \"700m\", 'filename' = \"newressusample1024.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"800m\", 'filename' = \"newressusample1025.rnd\", 'weak' = \"6\", 'failed' = \"1\"\n'input' = \"single\", 'filesize' = \"900m\", 'filename' = \"newressusample1026.rnd\", 'weak' = \"3\", 'failed' = \"3\"\n'input' = \"single\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1080.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1081.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"2g\", 'filename' = \"newressusample1082.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"3g\", 'filename' = \"newressusample1083.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"4g\", 'filename' = \"newressusample1084.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"5g\", 'filename' = \"newressusample1085.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"single\", 'filesize' = \"6g\", 'filename' = \"newressusample1086.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n$<\/code><\/pre>\n\n\n\n<p>Alkuper\u00e4isen &#8220;bad for randomness&#8221; koodin lista n\u00e4ytt\u00e4\u00e4 seuraavalta: (sek\u00e4 weak ett\u00e4 failed rivej\u00e4 on paljon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep ressubfr1 newressudieharder.skk\n'input' = \"ressubfr1\", 'filesize' = \"10g\", 'filename' = \"newressusample897.rnd\", 'weak' = \"12\", 'failed' = \"31\"\n'input' = \"ressubfr1\", 'filesize' = \"20g\", 'filename' = \"newressusample832.rnd\", 'weak' = \"8\", 'failed' = \"34\"\n'input' = \"ressubfr1\", 'filesize' = \"30g\", 'filename' = \"newressusample860.rnd\", 'weak' = \"9\", 'failed' = \"33\"\n'input' = \"ressubfr1\", 'filesize' = \"500m\", 'filename' = \"newressusample873.rnd\", 'weak' = \"11\", 'failed' = \"18\"\n'input' = \"ressubfr1\", 'filesize' = \"600m\", 'filename' = \"newressusample874.rnd\", 'weak' = \"14\", 'failed' = \"18\"\n'input' = \"ressubfr1\", 'filesize' = \"700m\", 'filename' = \"newressusample875.rnd\", 'weak' = \"12\", 'failed' = \"20\"\n'input' = \"ressubfr1\", 'filesize' = \"800m\", 'filename' = \"newressusample876.rnd\", 'weak' = \"6\", 'failed' = \"21\"\n'input' = \"ressubfr1\", 'filesize' = \"900m\", 'filename' = \"newressusample878.rnd\", 'weak' = \"15\", 'failed' = \"19\"\n'input' = \"ressubfr1\", 'filesize' = \"1g\", 'filename' = \"newressusample880.rnd\", 'weak' = \"8\", 'failed' = \"18\"\n'input' = \"ressubfr1\", 'filesize' = \"1g100m\", 'filename' = \"newressusample881.rnd\", 'weak' = \"9\", 'failed' = \"20\"\n'input' = \"ressubfr1\", 'filesize' = \"1g200m\", 'filename' = \"newressusample882.rnd\", 'weak' = \"13\", 'failed' = \"31\"\n'input' = \"ressubfr1\", 'filesize' = \"1g300m\", 'filename' = \"newressusample884.rnd\", 'weak' = \"14\", 'failed' = \"30\"\n'input' = \"ressubfr1\", 'filesize' = \"1g400m\", 'filename' = \"newressusample885.rnd\", 'weak' = \"6\", 'failed' = \"32\"\n'input' = \"ressubfr1\", 'filesize' = \"1g500m\", 'filename' = \"newressusample886.rnd\", 'weak' = \"9\", 'failed' = \"32\"\n'input' = \"ressubfr1\", 'filesize' = \"1g600m\", 'filename' = \"newressusample889.rnd\", 'weak' = \"10\", 'failed' = \"19\"\n'input' = \"ressubfr1\", 'filesize' = \"1g700m\", 'filename' = \"newressusample890.rnd\", 'weak' = \"7\", 'failed' = \"21\"\n'input' = \"ressubfr1\", 'filesize' = \"1g800m\", 'filename' = \"newressusample891.rnd\", 'weak' = \"8\", 'failed' = \"20\"\n'input' = \"ressubfr1\", 'filesize' = \"1g900m\", 'filename' = \"newressusample892.rnd\", 'weak' = \"8\", 'failed' = \"17\"\n'input' = \"ressubfr1\", 'filesize' = \"2g\", 'filename' = \"newressusample899.rnd\", 'weak' = \"6\", 'failed' = \"21\"\n'input' = \"ressubfr1\", 'filesize' = \"3g\", 'filename' = \"newressusample900.rnd\", 'weak' = \"9\", 'failed' = \"23\"\n'input' = \"ressubfr1\", 'filesize' = \"4g\", 'filename' = \"newressusample901.rnd\", 'weak' = \"13\", 'failed' = \"17\"\n'input' = \"ressubfr1\", 'filesize' = \"5g\", 'filename' = \"newressusample902.rnd\", 'weak' = \"9\", 'failed' = \"18\"\n'input' = \"ressubfr1\", 'filesize' = \"6g\", 'filename' = \"newressusample903.rnd\", 'weak' = \"4\", 'failed' = \"18\"\n$<\/code><\/pre>\n\n\n\n<p>&#8220;bad for randomness&#8221; koodin +2 versio: t\u00e4ss\u00e4kin weak ja failed rivej\u00e4 on paljon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep ressubfr2 newressudieharder.skk\n'input' = \"ressubfr2\", 'filesize' = \"1g200m\", 'filename' = \"newressusample932.rnd\", 'weak' = \"8\", 'failed' = \"22\"\n'input' = \"ressubfr2\", 'filesize' = \"1g300m\", 'filename' = \"newressusample933.rnd\", 'weak' = \"6\", 'failed' = \"20\"\n'input' = \"ressubfr2\", 'filesize' = \"1g400m\", 'filename' = \"newressusample934.rnd\", 'weak' = \"9\", 'failed' = \"17\"\n'input' = \"ressubfr2\", 'filesize' = \"1g500m\", 'filename' = \"newressusample935.rnd\", 'weak' = \"5\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"1g600m\", 'filename' = \"newressusample936.rnd\", 'weak' = \"10\", 'failed' = \"20\"\n'input' = \"ressubfr2\", 'filesize' = \"1g700m\", 'filename' = \"newressusample949.rnd\", 'weak' = \"13\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"10g\", 'filename' = \"newressusample950.rnd\", 'weak' = \"4\", 'failed' = \"22\"\n'input' = \"ressubfr2\", 'filesize' = \"20g\", 'filename' = \"newressusample961.rnd\", 'weak' = \"9\", 'failed' = \"16\"\n'input' = \"ressubfr2\", 'filesize' = \"30g\", 'filename' = \"newressusample962.rnd\", 'weak' = \"9\", 'failed' = \"17\"\n'input' = \"ressubfr2\", 'filesize' = \"500m\", 'filename' = \"newressusample904.rnd\", 'weak' = \"12\", 'failed' = \"17\"\n'input' = \"ressubfr2\", 'filesize' = \"600m\", 'filename' = \"newressusample980.rnd\", 'weak' = \"9\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"700m\", 'filename' = \"newressusample981.rnd\", 'weak' = \"14\", 'failed' = \"19\"\n'input' = \"ressubfr2\", 'filesize' = \"800m\", 'filename' = \"newressusample982.rnd\", 'weak' = \"12\", 'failed' = \"21\"\n'input' = \"ressubfr2\", 'filesize' = \"900m\", 'filename' = \"newressusample983.rnd\", 'weak' = \"13\", 'failed' = \"21\"\n'input' = \"ressubfr2\", 'filesize' = \"1g\", 'filename' = \"newressusample984.rnd\", 'weak' = \"9\", 'failed' = \"20\"\n'input' = \"ressubfr2\", 'filesize' = \"1g100m\", 'filename' = \"newressusample985.rnd\", 'weak' = \"12\", 'failed' = \"21\"\n'input' = \"ressubfr2\", 'filesize' = \"1g600m\", 'filename' = \"newressusample986.rnd\", 'weak' = \"11\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"1g700m\", 'filename' = \"newressusample987.rnd\", 'weak' = \"9\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"1g800m\", 'filename' = \"newressusample988.rnd\", 'weak' = \"8\", 'failed' = \"20\"\n'input' = \"ressubfr2\", 'filesize' = \"1g900m\", 'filename' = \"newressusample989.rnd\", 'weak' = \"11\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"2g\", 'filename' = \"newressusample990.rnd\", 'weak' = \"8\", 'failed' = \"18\"\n'input' = \"ressubfr2\", 'filesize' = \"3g\", 'filename' = \"newressusample991.rnd\", 'weak' = \"8\", 'failed' = \"17\"\n'input' = \"ressubfr2\", 'filesize' = \"4g\", 'filename' = \"newressusample992.rnd\", 'weak' = \"8\", 'failed' = \"21\"\n'input' = \"ressubfr2\", 'filesize' = \"5g\", 'filename' = \"newressusample993.rnd\", 'weak' = \"8\", 'failed' = \"17\"\n$ <\/code><\/pre>\n\n\n\n<p>T\u00e4m\u00e4 lista on tehty korjatulla &#8220;bad for randomness&#8221; -rutiinilla: &#8220;Vihdoinkin&#8221; ressurivitkin n\u00e4ytt\u00e4v\u00e4t hyvilt\u00e4, muutama weak ja ei failed rivej\u00e4 suurissa tiedostoissa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep \\\"ressu\\\" newressudieharder.skk\n'input' = \"ressu\", 'filesize' = \"1g200m\", 'filename' = \"newressusample837.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"500m\", 'filename' = \"newressusample1042.rnd\", 'weak' = \"6\", 'failed' = \"1\"\n'input' = \"ressu\", 'filesize' = \"600m\", 'filename' = \"newressusample1043.rnd\", 'weak' = \"6\", 'failed' = \"1\"\n'input' = \"ressu\", 'filesize' = \"700m\", 'filename' = \"newressusample1044.rnd\", 'weak' = \"7\", 'failed' = \"1\"\n'input' = \"ressu\", 'filesize' = \"800m\", 'filename' = \"newressusample1045.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"900m\", 'filename' = \"newressusample1046.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g\", 'filename' = \"newressusample1047.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g100m\", 'filename' = \"newressusample994.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1003.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g400m\", 'filename' = \"newressusample1004.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1005.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1006.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1007.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1036.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1037.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"ressu\", 'filesize' = \"2g\", 'filename' = \"newressusample1038.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n$<\/code><\/pre>\n\n\n\n<p>Ressun fast version lista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep fast newressudieharder.skk\n'input' = \"fast\", 'filesize' = \"500m\", 'filename' = \"newressusample1078.rnd\", 'weak' = \"2\", 'failed' = \"2\"\n'input' = \"fast\", 'filesize' = \"600m\", 'filename' = \"newressusample1079.rnd\", 'weak' = \"7\", 'failed' = \"2\"\n'input' = \"fast\", 'filesize' = \"700m\", 'filename' = \"newressusample1103.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"800m\", 'filename' = \"newressusample1144.rnd\", 'weak' = \"7\", 'failed' = \"1\"\n'input' = \"fast\", 'filesize' = \"900m\", 'filename' = \"newressusample1145.rnd\", 'weak' = \"3\", 'failed' = \"4\"\n'input' = \"fast\", 'filesize' = \"1g\", 'filename' = \"newressusample1146.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1147.rnd\", 'weak' = \"2\", 'failed' = \"1\"\n'input' = \"fast\", 'filesize' = \"1g200m\", 'filename' = \"newressusample1148.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1149.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g400m\", 'filename' = \"newressusample1150.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1151.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1152.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1153.rnd\", 'weak' = \"2\", 'failed' = \"1\"\n'input' = \"fast\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1154.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1155.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"2g\", 'filename' = \"newressusample1156.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"3g\", 'filename' = \"newressusample1157.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"4g\", 'filename' = \"newressusample1158.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"5g\", 'filename' = \"newressusample1159.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"fast\", 'filesize' = \"6g\", 'filename' = \"newressusample1160.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n$<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 pseudoressu:sta samanlainen lista: Pseudoressulista n\u00e4ytt\u00e4\u00e4 kanssa hyv\u00e4lt\u00e4, se on avaimia lukuunottamatta SHA256:n tulos. Avaimethan tulevat ressusta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep \\\"pseudoressu\\\" newressudieharder.skk\n'input' = \"pseudoressu\", 'filesize' = \"1g\", 'filename' = \"newressusample802.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"500m\", 'filename' = \"newressusample905.rnd\", 'weak' = \"7\", 'failed' = \"1\"\n'input' = \"pseudoressu\", 'filesize' = \"600m\", 'filename' = \"newressusample906.rnd\", 'weak' = \"8\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"700m\", 'filename' = \"newressusample907.rnd\", 'weak' = \"11\", 'failed' = \"1\"\n'input' = \"pseudoressu\", 'filesize' = \"800m\", 'filename' = \"newressusample908.rnd\", 'weak' = \"2\", 'failed' = \"1\"\n'input' = \"pseudoressu\", 'filesize' = \"900m\", 'filename' = \"newressusample909.rnd\", 'weak' = \"5\", 'failed' = \"2\"\n'input' = \"pseudoressu\", 'filesize' = \"1g\", 'filename' = \"newressusample910.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g100m\", 'filename' = \"newressusample911.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g200m\", 'filename' = \"newressusample912.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g300m\", 'filename' = \"newressusample922.rnd\", 'weak' = \"2\", 'failed' = \"1\"\n'input' = \"pseudoressu\", 'filesize' = \"1g400m\", 'filename' = \"newressusample824.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g500m\", 'filename' = \"newressusample923.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g600m\", 'filename' = \"newressusample924.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g700m\", 'filename' = \"newressusample925.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g800m\", 'filename' = \"newressusample926.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"1g900m\", 'filename' = \"newressusample927.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"2g\", 'filename' = \"newressusample928.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"3g\", 'filename' = \"newressusample929.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"4g\", 'filename' = \"newressusample930.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"5g\", 'filename' = \"newressusample943.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"pseudoressu\", 'filesize' = \"6g\", 'filename' = \"newressusample944.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n$ <\/code><\/pre>\n\n\n\n<p>Stream l\u00e4hteen tuloskin on hyv\u00e4 lista: t\u00e4ss\u00e4 listassa ei oikeasti ole mit\u00e4\u00e4n satunnaista, kaikki merkit tulevat avaimesta &#8216;kalakala&#8217;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep \\\"stream\\\" newressudieharder.skk\n'input' = \"stream\", 'filesize' = \"500m\", 'filename' = \"newressusample955.rnd\", 'weak' = \"2\", 'failed' = \"2\"\n'input' = \"stream\", 'filesize' = \"600m\", 'filename' = \"newressusample956.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"700m\", 'filename' = \"newressusample957.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"stream\", 'filesize' = \"800m\", 'filename' = \"newressusample958.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"900m\", 'filename' = \"newressusample959.rnd\", 'weak' = \"8\", 'failed' = \"1\"\n'input' = \"stream\", 'filesize' = \"1g\", 'filename' = \"newressusample960.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g100m\", 'filename' = \"newressusample963.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g200m\", 'filename' = \"newressusample964.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g300m\", 'filename' = \"newressusample965.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"stream\", 'filesize' = \"1g500m\", 'filename' = \"newressusample966.rnd\", 'weak' = \"5\", 'failed' = \"1\"\n'input' = \"stream\", 'filesize' = \"1g600m\", 'filename' = \"newressusample967.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g700m\", 'filename' = \"newressusample968.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g800m\", 'filename' = \"newressusample969.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"1g900m\", 'filename' = \"newressusample970.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"2g\", 'filename' = \"newressusample971.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"3g\", 'filename' = \"newressusample972.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"4g\", 'filename' = \"newressusample973.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"5g\", 'filename' = \"newressusample974.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream\", 'filesize' = \"6g\", 'filename' = \"newressusample975.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n$ \n<\/code><\/pre>\n\n\n\n<p>Uusi ajo &#8211;stream optiolla: kuten odotin, lista n\u00e4ytt\u00e4\u00e4 samalta edellisen stream listan kanssa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep stream2 newressudieharder.skk\n'input' = \"stream2\", 'filesize' = \"500m\", 'filename' = \"newressusample1124.rnd\", 'weak' = \"2\", 'failed' = \"2\"\n'input' = \"stream2\", 'filesize' = \"600m\", 'filename' = \"newressusample1125.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"700m\", 'filename' = \"newressusample1126.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"stream2\", 'filesize' = \"800m\", 'filename' = \"newressusample1127.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"900m\", 'filename' = \"newressusample1128.rnd\", 'weak' = \"8\", 'failed' = \"1\"\n'input' = \"stream2\", 'filesize' = \"1g\", 'filename' = \"newressusample1129.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1130.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g200m\", 'filename' = \"newressusample1131.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1132.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"stream2\", 'filesize' = \"1g400m\", 'filename' = \"newressusample1133.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"stream2\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1134.rnd\", 'weak' = \"5\", 'failed' = \"1\"\n'input' = \"stream2\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1135.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1136.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1137.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1138.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"2g\", 'filename' = \"newressusample1139.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"3g\", 'filename' = \"newressusample1140.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"4g\", 'filename' = \"newressusample1141.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"5g\", 'filename' = \"newressusample1142.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"stream2\", 'filesize' = \"6g\", 'filename' = \"newressusample1143.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n$ <\/code><\/pre>\n\n\n\n<p>Rdrand, eli intel prosessorin tarjoama satunnaisuus on kanssa &#8211;dieharder mieless\u00e4 ok.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep \\\"rdrand\\\" newressudieharder.skk\n'input' = \"rdrand\", 'filesize' = \"500m\", 'filename' = \"newressusample995.rnd\", 'weak' = \"5\", 'failed' = \"2\"\n'input' = \"rdrand\", 'filesize' = \"600m\", 'filename' = \"newressusample996.rnd\", 'weak' = \"3\", 'failed' = \"4\"\n'input' = \"rdrand\", 'filesize' = \"700m\", 'filename' = \"newressusample997.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"rdrand\", 'filesize' = \"800m\", 'filename' = \"newressusample998.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"900m\", 'filename' = \"newressusample999.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"rdrand\", 'filesize' = \"1g\", 'filename' = \"newressusample1000.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1001.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g200m\", 'filename' = \"newressusample827.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1039.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"rdrand\", 'filesize' = \"1g400m\", 'filename' = \"newressusample862.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1040.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1041.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1048.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"rdrand\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1049.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1050.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"2g\", 'filename' = \"newressusample1051.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"3g\", 'filename' = \"newressusample1052.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"rdrand\", 'filesize' = \"4g\", 'filename' = \"newressusample1053.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"5g\", 'filename' = \"newressusample1073.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"rdrand\", 'filesize' = \"6g\", 'filename' = \"newressusample1074.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n$ <\/code><\/pre>\n\n\n\n<p>Ja toinen intel tuote &#8211;rdseed: &#8211;dieharder ok. N\u00e4ist\u00e4 l\u00f6yd\u00e4t keskustelua netist\u00e4. Ne ovat newressussa valinnaisia.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ grep \\\"rdseed\\\" newressudieharder.skk\n'input' = \"rdseed\", 'filesize' = \"500m\", 'filename' = \"newressusample937.rnd\", 'weak' = \"7\", 'failed' = \"2\"\n'input' = \"rdseed\", 'filesize' = \"600m\", 'filename' = \"newressusample938.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"700m\", 'filename' = \"newressusample939.rnd\", 'weak' = \"12\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"800m\", 'filename' = \"newressusample940.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"900m\", 'filename' = \"newressusample941.rnd\", 'weak' = \"9\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g\", 'filename' = \"newressusample942.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1087.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g200m\", 'filename' = \"newressusample835.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1088.rnd\", 'weak' = \"8\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g400m\", 'filename' = \"newressusample863.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1089.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1090.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1091.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1092.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1093.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"2g\", 'filename' = \"newressusample1094.rnd\", 'weak' = \"8\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"3g\", 'filename' = \"newressusample1095.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"4g\", 'filename' = \"newressusample1096.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"5g\", 'filename' = \"newressusample1097.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"rdseed\", 'filesize' = \"6g\", 'filename' = \"newressusample1098.rnd\", 'weak' = \"0\", 'failed' = \"0\"\n$<\/code><\/pre>\n\n\n\n<p>Edellinen lista edellisest\u00e4 ressutwist generaattorista:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'input' = \"ressutwist\", 'filesize' = \"500m\", 'filename' = \"newressusample1751.rnd\", 'weak' = \"5\", 'failed' = \"1\"\n'input' = \"ressutwist\", 'filesize' = \"600m\", 'filename' = \"newressusample1752.rnd\", 'weak' = \"8\", 'failed' = \"1\"\n'input' = \"ressutwist\", 'filesize' = \"700m\", 'filename' = \"newressusample1753.rnd\", 'weak' = \"6\", 'failed' = \"2\"\n'input' = \"ressutwist\", 'filesize' = \"800m\", 'filename' = \"newressusample1754.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"900m\", 'filename' = \"newressusample1755.rnd\", 'weak' = \"3\", 'failed' = \"2\"\n'input' = \"ressutwist\", 'filesize' = \"1g\", 'filename' = \"newressusample1756.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g100m\", 'filename' = \"newressusample1757.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"ressutwist\", 'filesize' = \"1g200m\", 'filename' = \"newressusample1758.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g300m\", 'filename' = \"newressusample1759.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"ressutwist\", 'filesize' = \"1g400m\", 'filename' = \"newressusample1760.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g500m\", 'filename' = \"newressusample1761.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g600m\", 'filename' = \"newressusample1762.rnd\", 'weak' = \"7\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g700m\", 'filename' = \"newressusample1763.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g800m\", 'filename' = \"newressusample1764.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"1g900m\", 'filename' = \"newressusample1773.rnd\", 'weak' = \"4\", 'failed' = \"1\"\n'input' = \"ressutwist\", 'filesize' = \"2g\", 'filename' = \"newressusample1774.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"3g\", 'filename' = \"newressusample1775.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"4g\", 'filename' = \"newressusample1776.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"5g\", 'filename' = \"newressusample1777.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"ressutwist\", 'filesize' = \"6g\", 'filename' = \"newressusample1778.rnd\", 'weak' = \"3\", 'failed' = \"0\"<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty newressu:un test_bytes() -funktio, johon voit kirjoittaa oman satunnaisbittigeneraattorisi, ja ajaa sit\u00e4 &#8211;test komentorivioptiolla. T\u00e4ll\u00f6in kaikki newressu:un toiminnot ja newressutest? ohjelmat ovat k\u00e4yt\u00f6ss\u00e4si generaattorin testaamiseen. T\u00e4ll\u00e4 hetkell\u00e4 test_bytes() funktio palauttaa koko puskurin t\u00e4ynn\u00e4 nollia. &#8211;dieharder ei jostain syyst\u00e4 toimi kunnolla jos satunnaismerkit ovat pelkki\u00e4 nollia.<\/p>\n\n\n\n<p>Test koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void test_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  \/\/ insert your generator here, run it with --test command parameter\n  \n  memset(buffer, 0, size);\n}\n\nint newressu_genbyte()\n{\n....\n    else if(input == INPUT_TEST) \/\/ test generator\n      test_bytes(sizeof(gent), gent);\n\n----\n}\n\nvoid dump_sample() \/\/ &amp; dieharder analysis\n{\n....\n      else if(input == INPUT_TEST) \/\/ test generator\n\ttest_bytes(blocksize, buffer);\n....\n}\n\nint main(int argc, char *argv&#91;])\n{\n....\n      } else if(!strcmp(\"--test\", argv&#91;c])) { \/\/ test generator\n\tinput = INPUT_TEST;\n\tinput_str = argv&#91;c] + 2;\n      }\n....\n  if(input == INPUT_TEST) {\n    fprintf(stderr,\"%s: randomness from your generator (test_bytes)\\n\", procname);\n  }\n....\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 satunnaisuutta &#8211;test oletuskoodilla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --test\n.\/newressu: randomness from your generator (test_bytes)\n00000 00000000000000000000000000000000000000000000000000000000000000000\n00001 00000000000000000000000000000000000000000000000000000000000000000\n00002 00000000000000000000000000000000000000000000000000000000000000000\n00003 00000000000000000000000000000000000000000000000000000000000000000\n00004 00000000000000000000000000000000000000000000000000000000000000000\n00005 00000000000000000000000000000000000000000000000000000000000000000\n00006 00000000000000000000000000000000000000000000000000000000000000000\n00007 00000000000000000000000000000000000000000000000000000000000000000\n00008 00000000000000000000000000000000000000000000000000000000000000000\n00009 00000000000000000000000000000000000000000000000000000000000000000\n$ <\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty test_bytes testirutiiniin ressun, pseudoressun ja \/dev\/urandom:in yhdistelm\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void test_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  \/\/ insert your generator here, run it with\n  \/\/ --test command line parameter (source for\n  \/\/ randomness)\n\n  ressutwist_bytes(size, buffer);\n  urandom_bytes(size, buffer);\n  \n  \/\/memset(buffer, 0, size);\n\n  \/\/for(int c = 0; c &lt; size; c++)\n  \/\/  buffer&#91;c] = c &amp; 0xff;\n}\n<\/code><\/pre>\n\n\n\n<p>Ja ajettu edellinen testiscripti test generaattorilla: ressu-pseudoressu-urandom yhdistelm\u00e4ll\u00e4kin tulos on &#8211;dieharder kelpoinen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'input' = \"test\", 'filesize' = \"500m\", 'filename' = \"newressusample2665.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"600m\", 'filename' = \"newressusample2666.rnd\", 'weak' = \"6\", 'failed' = \"3\"\n'input' = \"test\", 'filesize' = \"700m\", 'filename' = \"newressusample2667.rnd\", 'weak' = \"10\", 'failed' = \"1\"\n'input' = \"test\", 'filesize' = \"800m\", 'filename' = \"newressusample2668.rnd\", 'weak' = \"3\", 'failed' = \"2\"\n'input' = \"test\", 'filesize' = \"900m\", 'filename' = \"newressusample2669.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"test\", 'filesize' = \"1g\", 'filename' = \"newressusample2670.rnd\", 'weak' = \"3\", 'failed' = \"1\"\n'input' = \"test\", 'filesize' = \"1g100m\", 'filename' = \"newressusample2671.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g200m\", 'filename' = \"newressusample2672.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g300m\", 'filename' = \"newressusample2673.rnd\", 'weak' = \"2\", 'failed' = \"1\"\n'input' = \"test\", 'filesize' = \"1g400m\", 'filename' = \"newressusample2674.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g500m\", 'filename' = \"newressusample2675.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g600m\", 'filename' = \"newressusample2676.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g700m\", 'filename' = \"newressusample2677.rnd\", 'weak' = \"2\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g800m\", 'filename' = \"newressusample2678.rnd\", 'weak' = \"6\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"1g900m\", 'filename' = \"newressusample2679.rnd\", 'weak' = \"1\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"2g\", 'filename' = \"newressusample2680.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"3g\", 'filename' = \"newressusample2681.rnd\", 'weak' = \"5\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"4g\", 'filename' = \"newressusample2682.rnd\", 'weak' = \"4\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"5g\", 'filename' = \"newressusample2683.rnd\", 'weak' = \"3\", 'failed' = \"0\"\n'input' = \"test\", 'filesize' = \"6g\", 'filename' = \"newressusample2684.rnd\", 'weak' = \"4\", 'failed' = \"0\"<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty uusi komentoriviparametri &#8211;base, jolla voi tulostaa satunnaislukuja numeroj\u00e4rjestelm\u00e4n kantaluvulla: esimerkiksi &#8211;base2 tulostaa bin\u00e4\u00e4risi\u00e4 lukuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base2 --space\n00000  11000100 01111111 11001101 00011101 00010110 11100110 11010111\n00001  01001011 10110000 10001001 00100010 00111100 00100010 00111001\n00002  01001110 01110111 10001111 01111110 10000100 01100011 01000001\n00003  01110111 11001010 00011001 11110001 01101000 11111000 00011000\n00004  10000101 10001100 00010101 00010100 10100010 11111000 11111100\n00005  11100110 10111110 01000000 01001011 01011000 01101000 10000111\n00006  11000101 01100011 11000011 01010010 01100101 01101000 01110100\n00007  10001001 10110101 01000100 10100010 10100101 00111101 01110010\n00008  00101000 00011010 11000000 00011011 11101100 11110011 01110001\n00009  00111100 11101110 01101100 00100011 10100010 10101011 01110010\n$ <\/code><\/pre>\n\n\n\n<p>&#8211;base8 Tulostaa oktaalisia lukuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base8 --space\n00000  555 577 571 453 417 713 524 041 350 116 445 542 630 601 101 063\n00001  110 137 621 616 464 522 350 133 141 516 440 030 276 666 025 041\n00002  722 142 746 011 005 570 526 245 065 113 063 012 037 734 450 664\n00003  055 652 736 117 031 130 673 271 700 500 573 752 344 545 137 664\n00004  707 527 155 352 163 075 363 256 061 763 374 541 372 452 550 745\n00005  350 435 256 756 356 763 454 472 170 523 442 513 662 022 002 442\n00006  627 647 504 635 317 431 241 253 347 641 640 102 436 255 202 137\n00007  450 066 722 262 331 446 336 750 607 650 143 172 522 105 424 207\n00008  012 004 751 651 634 314 721 755 462 450 507 014 306 236 653 053\n00009  211 057 450 474 524 047 017 346 211 071 235 501 626 474 715 175\n$ <\/code><\/pre>\n\n\n\n<p>&#8211;base10 tulostaa desimaalisia lukuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base10 --space\n00000  95115 37937 89506 93199 97183 10901 23222 55074 57325 64779 14185\n00001  51276 53941 32097 46818 39443 36891 04676 65278 82499 99531 14515\n00002  83199 80506 17322 72150 41682 57004 48748 82340 77278 23999 48218\n00003  60605 83877 91724 87016 18583 08774 07189 93432 28636 75338 33974\n00004  30782 37979 14311 64447 42103 93364 15366 28464 50557 93526 37781\n00005  48320 15913 14301 24410 93099 97241 65875 61581 43909 32427 94536\n00006  96746 50411 50162 12843 31785 30160 37329 05794 66353 91398 38261\n00007  75387 17734 87459 97700 02426 44844 07538 93280 86564 39398 35084\n00008  92139 68175 16288 09362 65059 77951 77617 16583 71273 09692 13384\n00009  06691 06553 33780 39081 64955 58401 92144 49439 40880 35723 89259\n$ <\/code><\/pre>\n\n\n\n<p>&#8211;base16 tulostaa heksadesimaalilukuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base16 --space\n00000  4c37 8c70 bc04 6810 05b8 ed49 3177 19f7 17cc adb2 29d0 f020 621a\n00001  b172 b32c 1ab5 a032 9d63 bc53 f412 0037 eefc d3d7 c8b1 978c 2099\n00002  c22c fbed f611 32ad d5fe d4c4 3ba2 7e37 ab79 2342 5c69 aef0 7599\n00003  29cc 01ec 005b 037f 53ab 8961 1140 35e3 3719 0580 ab56 fe80 2177\n00004  d9df 80b6 3701 2682 d4e4 880c 030c f534 e84e 7017 379a f30e 0480\n00005  371f 2b47 59cf 8ac2 4380 64d1 dd7b f1f7 a838 b2ad d3f9 8a03 0573\n00006  3f1e 6f0c 0514 ef54 7312 a380 0d3c 6150 cdaa 15cd dace 4395 5d4b\n00007  e898 84e8 c85f 39e7 5e50 013a da26 dc00 c447 7487 3b08 8dde c410\n00008  f10a 14c7 128d fa4d 6732 f56e 5ea7 f77e 970f d164 daaf dc6b f255\n00009  19f4 0c41 1ca1 ce7c 7466 0422 0943 af04 72c5 007a 480a 6dc6 7804\n$ <\/code><\/pre>\n\n\n\n<p>Edell\u00e4 olivat perus numeroj\u00e4rjestelm\u00e4t bin\u00e4\u00e4ri, oktaali, desimaali ja heksadesimaali, mutta &#8211;base toimii my\u00f6s muilla kantaluvuilla (2-64): esimerkiksi &#8211;base36 tulostaa 36 kantaisen numeroj\u00e4rjestelm\u00e4n lukuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base36 --space\n00000  vw6t4707 wmzejmor jnacj3wx pbytkend szssa2dt u29rofy4 7ddvaowo\n00001  gxyyprag w2m2t8il h0rcz7zz 0a8j9z2p mrczccyl qj592k9w lj3obm93\n00002  6oh3zd8d fpluix1l rcyjaeqt oynw60up 2763qwu1 891zbfls egwb6lvq\n00003  x14rnc4f kuv2kz3p et1topzo 3imwi0li 7jzzf2w4 ks06zhuk 2xo1rog8\n00004  d2gdqkfx v4bsh2w0 7uxk55wp ey2l6f7u ixcl2sab ue8tj2wy mxeuqsx0\n00005  s51oe413 8zr2iifo xo93c33h 8iveqio1 zbmwvpnc clzy8vng 6bz994j4\n00006  8b3z7870 7jzekf1v btzmmq4w 02v09ecd 2ic974kw 3w99jvxy 30z5z9yj\n00007  p10k2f02 jqp7xc7f 0mjc41q5 molcvqmy goxbzcat p4e75z9h 16lm6mgr\n00008  szn5d1v8 leepjby0 j08fhhf3 bn1hrd12 nji2qc6l 5oszvwxv uzufl14b\n00009  rws9u11f x33fapt2 oub6phs2 91g8vl7p eas829wa b5q7z29s k724s4p9\n$<\/code><\/pre>\n\n\n\n<p>36-kantaisessa numeroj\u00e4rjestelm\u00e4ss\u00e4 on numerot ja kaikki pienet kirjaimet. ([0-9]+[a-z] = 10 + 26 = 36). Seuraavassa koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char *basedigits = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-\";\n....\nint main(int argc, char *argv&#91;])\n{\n....\n      } else if(!strncmp(\"--base\", argv&#91;c], 6)) {\n\n\tif(*(argv&#91;c] + 6) != '\\0') {\n\t  base = atoll(argv&#91;c] + 6);\n\t} else if(c + 1 &lt; argc) {\n\t  base = atoll(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tif(base &lt; 2 || base &gt; 64)\n\t  base = -1;\n\t\n      } else if(!strncmp(\"--BASE\", argv&#91;c], 6)) {\n\n\tif(*(argv&#91;c] + 6) != '\\0') {\n\t  base = atoll(argv&#91;c] + 6);\n\t  uppercase = 1;\n\t} else if(c + 1 &lt; argc) {\n\t  base = atoll(argv&#91;c + 1]);\n\t  uppercase = 1;\n\t  c++;\n\t}\n\tif(base &lt; 2 || base &gt; 64) {\n\t  base = -1;\n\t  uppercase = -1;\n\t}   \n....'\n      } else if(!strcmp(\"-b\", argv&#91;c]) ||\n\t\t!strcmp(\"--bin\", argv&#91;c]) ||\n\t\t!strcmp(\"--1bit\", argv&#91;c]) ||\n\t\t!strcmp(\"--1bits\", argv&#91;c])) {\n\n\tbase = 2;\n\t\n      } else if(!strcmp(\"--2bits\", argv&#91;c])) {\n\n\tbase = 4;\n\n      } else if(!strcmp(\"-o\", argv&#91;c]) ||\n\t\t!strcmp(\"--oct\", argv&#91;c]) ||\n\t\t!strcmp(\"--3bits\", argv&#91;c]) ) {\n\n\tbase = 8;\n\n      } else if(!strcmp(\"-d\", argv&#91;c]) ||\n\t\t!strcmp(\"--dec\", argv&#91;c])) {\n\n\tbase = 10;\n\n      } else if(!strcmp(\"-x\", argv&#91;c]) ||\n\t\t!strcmp(\"--hex\", argv&#91;c]) ||\n\t\t!strcmp(\"--4bits\", argv&#91;c])) {\n\n\tbase = 16;\n\n      } else if(!strcmp(\"-X\", argv&#91;c]) ||\n\t\t!strcmp(\"--HEX\", argv&#91;c]) ||\n\t\t!strcmp(\"--4BITS\", argv&#91;c])) {\n\n\tbase = 16;\n\tuppercase = 1;\n\n      } else if(!strcmp(\"-5\", argv&#91;c]) ||\n\t\t!strcmp(\"--5bits\", argv&#91;c])) {\n\n\tbase = 32;\n\t\n      } else if(!strcmp(\"--5BITS\", argv&#91;c])) {\n\n\tbase = 32;\n\tuppercase = 1;\n\t\n      } else if(!strcmp(\"-2\", argv&#91;c]) ||\n\t\t!strcmp(\"--6bits\", argv&#91;c])) {\n\n\tbase = 64;\n\t\n....\n  if(size == -1) {\n    if(base == 2)\n      size = 8;\n    else if(base == 8)\n      size = 3;\n    else if(base == 10)\n      size = 5;\n    else if(base == 16)\n      size = 4;\n    else\n      size = 8;\n  }\n\n  if(base == -1) {\n    base = 10;\n  } else {\n    digits = malloc(base + 1);\n    strncpy(digits, basedigits, base);\n    if(uppercase == 1 &amp;&amp; base &lt;= 36) { \/\/ if lowercase only (&#91;0-9] + &#91;a-z], 10 + 26\n      for(int c = 0; c &lt; base; c++) { \/\/ to uppercase\n        if(digits&#91;c] &gt;= 'a' &amp;&amp; digits&#91;c] &lt;= 'z')\n          digits&#91;c] = digits&#91;c] - 'a' + 'A';\n        else if(digits&#91;c] &gt;= 'A' &amp;&amp; digits&#91;c] &lt;= 'Z')\n          digits&#91;c] = digits&#91;c] - 'A' + 'a';\n      }\n    }\n\n    digits&#91;base] = '\\0';\n\n    digitsext = digits;\n    \n    charspaces = 0;\n    charwidth = 1;\n  }\n....\n}<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 &#8211;base toiminnon tarkistamiseen k\u00e4ytettyj\u00e4 debukkeja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG67\n\n#ifdef DEBUG67\n  unsigned long long big = 0xffffffffffffffff;\n  fprintf(stdout,\"\\n0x%llx\\n\", big);\n  fprintfbase(stdout, big, 2);\n  fprintf(stdout,\"\\n0o%llo\\n\", big);\n  fprintfbase(stdout, big, 8);\n  fprintf(stdout,\"\\n0d%llu\\n\", big);\n  fprintfbase(stdout, big, 10);\n  fprintf(stdout,\"\\n0x%llx\\n\", big);\n  fprintfbase(stdout, big, 16);\n  fprintf(stdout,\"\\n\");\n\n  \/\/for(unsigned long long ll = 4096; ll &gt; 0; ll+=4096) {\n  for(unsigned long long ll = 0; ll &lt; 1047576; ll++) {\n  \/\/for(unsigned long long ll = 1; ll != 0; ll *= 2) {\n    fprintf(stdout,\"%llu:\", ll);\n    fflush(stdout);\n    for(int base = 2; base &lt;= 64; base++) {\n      fprintf(stdout,\" \");\n      fprintfbase(stdout, ll, base);\n      fflush(stdout);\n    }\n    fprintf(stdout,\"\\n\");\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Edellinen debukki suoritetaan ennen newressu:n alkua main() rutiinissa. Se tulostaa seuraavanlaisen listan: Vasemmassa reunassa on desimaalij\u00e4rjestelm\u00e4n numero ja siit\u00e4 oikealle on eri numeroj\u00e4rjestelmien numerot 2-j\u00e4rjestelm\u00e4st\u00e4 (bin\u00e4\u00e4ri) 64 j\u00e4rjestelm\u00e4\u00e4n. Bin\u00e4\u00e4riluvut, oktaaliluvut desimaaliluvut ja heksadesimaaliluvut on aloitettu totutuilla prefix:eill\u00e4 0b, 0o, 0d ja 0x.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0: 0b0 0 0 0 0 0 0o0 0 0d0 0 0 0 0 0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n1: 0b1 1 1 1 1 1 0o1 1 0d1 1 1 1 1 1 0x1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n2: 0b10 2 2 2 2 2 0o2 2 0d2 2 2 2 2 2 0x2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n3: 0b11 10 3 3 3 3 0o3 3 0d3 3 3 3 3 3 0x3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3\n4: 0b100 11 10 4 4 4 0o4 4 0d4 4 4 4 4 4 0x4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4\n5: 0b101 12 11 10 5 5 0o5 5 0d5 5 5 5 5 5 0x5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5\n6: 0b110 20 12 11 10 6 0o6 6 0d6 6 6 6 6 6 0x6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6\n7: 0b111 21 13 12 11 10 0o7 7 0d7 7 7 7 7 7 0x7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7\n8: 0b1000 22 20 13 12 11 0o10 8 0d8 8 8 8 8 8 0x8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8\n9: 0b1001 100 21 14 13 12 0o11 10 0d9 9 9 9 9 9 0x9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9\n10: 0b1010 101 22 20 14 13 0o12 11 0d10 a a a a a 0xa a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a\n11: 0b1011 102 23 21 15 14 0o13 12 0d11 10 b b b b 0xb b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b\n12: 0b1100 110 30 22 20 15 0o14 13 0d12 11 10 c c c 0xc c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c\n13: 0b1101 111 31 23 21 16 0o15 14 0d13 12 11 10 d d 0xd d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d\n14: 0b1110 112 32 24 22 20 0o16 15 0d14 13 12 11 10 e 0xe e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e\n15: 0b1111 120 33 30 23 21 0o17 16 0d15 14 13 12 11 10 0xf f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f\n16: 0b10000 121 100 31 24 22 0o20 17 0d16 15 14 13 12 11 0x10 g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g\n17: 0b10001 122 101 32 25 23 0o21 18 0d17 16 15 14 13 12 0x11 10 h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h\n18: 0b10010 200 102 33 30 24 0o22 20 0d18 17 16 15 14 13 0x12 11 10 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i\n19: 0b10011 201 103 34 31 25 0o23 21 0d19 18 17 16 15 14 0x13 12 11 10 j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j\n20: 0b10100 202 110 40 32 26 0o24 22 0d20 19 18 17 16 15 0x14 13 12 11 10 k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k\n21: 0b10101 210 111 41 33 30 0o25 23 0d21 1a 19 18 17 16 0x15 14 13 12 11 10 l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l\n22: 0b10110 211 112 42 34 31 0o26 24 0d22 20 1a 19 18 17 0x16 15 14 13 12 11 10 m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m\n23: 0b10111 212 113 43 35 32 0o27 25 0d23 21 1b 1a 19 18 0x17 16 15 14 13 12 11 10 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n\n24: 0b11000 220 120 44 40 33 0o30 26 0d24 22 20 1b 1a 19 0x18 17 16 15 14 13 12 11 10 o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o\n25: 0b11001 221 121 100 41 34 0o31 27 0d25 23 21 1c 1b 1a 0x19 18 17 16 15 14 13 12 11 10 p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p\n26: 0b11010 222 122 101 42 35 0o32 28 0d26 24 22 20 1c 1b 0x1a 19 18 17 16 15 14 13 12 11 10 q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q\n27: 0b11011 1000 123 102 43 36 0o33 30 0d27 25 23 21 1d 1c 0x1b 1a 19 18 17 16 15 14 13 12 11 10 r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r\n28: 0b11100 1001 130 103 44 40 0o34 31 0d28 26 24 22 20 1d 0x1c 1b 1a 19 18 17 16 15 14 13 12 11 10 s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s\n29: 0b11101 1002 131 104 45 41 0o35 32 0d29 27 25 23 21 1e 0x1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t t\n30: 0b11110 1010 132 110 50 42 0o36 33 0d30 28 26 24 22 20 0x1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u\n31: 0b11111 1011 133 111 51 43 0o37 34 0d31 29 27 25 23 21 0x1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v\n32: 0b100000 1012 200 112 52 44 0o40 35 0d32 2a 28 26 24 22 0x20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w\n33: 0b100001 1020 201 113 53 45 0o41 36 0d33 30 29 27 25 23 0x21 1g 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x\n34: 0b100010 1021 202 114 54 46 0o42 37 0d34 31 2a 28 26 24 0x22 20 1g 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y\n35: 0b100011 1022 203 120 55 50 0o43 38 0d35 32 2b 29 27 25 0x23 21 1h 1g 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 z z z z z z z z z z z z z z z z z z z z z z z z z z z z z<\/code><\/pre>\n\n\n\n<p>Toinen debukki on jo vanha, mutta sit\u00e4 on hiukan p\u00e4ivitetty: se on DEBUG24 seuraavassa gen_limit() rutiinissa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG24 2\n\nunsigned long newressu_gen_limit(unsigned long limit) \/\/ JariK 2022\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) { \/\/ one byte\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n\n    } else if(limit &lt;= 0x10000) { \/\/ two bytes\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n\n    } else if(limit &lt;= 0x1000000) { \/\/ three bytes\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n\n    } else if(limit &lt;= 0x100000000) { \/\/ four bytes\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n\n    } else if(limit &lt;= 0x10000000000) { \/\/ five bytes\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n\n    } else if(limit &lt;= 0x1000000000000) { \/\/ six bytes\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n\n    } else if(limit &lt;= 0x100000000000000) { \/\/ seven bytes\n      highlimit = (0x100000000000000 \/ limit) * limit;      \n      bytes = 7;\n\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n\n    }\n  } \/\/ if(lastlimit != limit\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n#ifdef DEBUG24\n  fprintf(stdout,\"\/\");\n  fprintf(stdout,\"%d bytes: \", bytes);\n  fprintf(stdout,\"&#91;\");\n  if(base == -1)\n    fprintfbase(stdout, word, 16);\n  else\n    fprintfbase(stdout, word, base);\n  fprintf(stdout,\"]\");\n  fprintf(stdout,\"\/\");\n  fflush(stdout);\n#endif\n\n  return(word);\n}<\/code><\/pre>\n\n\n\n<p>DEBUG24 tulostaa seuraavan listan: Listalla hakasulkeiden v\u00e4liss\u00e4 on satunnaisluku halutussa numeroj\u00e4rjestelm\u00e4ss\u00e4 ja kauttaviivojen v\u00e4liss\u00e4 on newressu:n tulostama osa. Debukkailussa vertaillaan vaan n\u00e4it\u00e4 lukuja kesken\u00e4\u00e4n, jos ne poikkeavat, kysymys voi olla bugista.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --base36\n\/6 bytes: &#91;s8mgcnh3]\/00000 s8mgcnh3\/6 bytes: &#91;9k2ib3e1]\/9k2ib3e1\/6 bytes: &#91;9wp3bkxs]\/9wp3bkxs\/6 bytes: &#91;518vdcat]\/518vdcat\/6 bytes: &#91;ngdb4pp7]\/ngdb4pp7\/6 bytes: &#91;rpttb929]\/rpttb929\/6 bytes: &#91;lwo0fh64]\/lwo0fh64\/6 bytes: &#91;hnb2u25m]\/hnb2u25m\n\/6 bytes: &#91;skbzruoy]\/00001 skbzruoy\/6 bytes: &#91;sm3zjnoj]\/sm3zjnoj\/6 bytes: &#91;8oypbwn7]\/8oypbwn7\/6 bytes: &#91;41gq1eiw]\/41gq1eiw\/6 bytes: &#91;z3o8q3sp]\/z3o8q3sp\/6 bytes: &#91;tmtmov02]\/tmtmov02\/6 bytes: &#91;9t0wdd6k]\/9t0wdd6k\/6 bytes: &#91;4493jrr9]\/4493jrr9\n\/6 bytes: &#91;lfjc14j4]\/00002 lfjc14j4\/6 bytes: &#91;q1eg504x]\/q1eg504x\/6 bytes: &#91;l4pj6fo6]\/l4pj6fo6\/6 bytes: &#91;mg5b9kwl]\/mg5b9kwl\/6 bytes: &#91;zfk08not]\/zfk08not\/6 bytes: &#91;srd8rz6v]\/srd8rz6v\/6 bytes: &#91;m1zf881h]\/m1zf881h\/6 bytes: &#91;51gvzg98]\/51gvzg98\n\/6 bytes: &#91;qdwjg75r]\/00003 qdwjg75r\/6 bytes: &#91;6xgb7i7]\/06xgb7i7\/6 bytes: &#91;jhqu1f3p]\/jhqu1f3p\/6 bytes: &#91;fwyo6fal]\/fwyo6fal\/6 bytes: &#91;n6dgl1wy]\/n6dgl1wy\/6 bytes: &#91;mvco358n]\/mvco358n\/6 bytes: &#91;siqxwadz]\/siqxwadz\/6 bytes: &#91;bm64i7dy]\/bm64i7dy\n\/6 bytes: &#91;brgihpa2]\/00004 brgihpa2\/6 bytes: &#91;ysj25oc3]\/ysj25oc3\/6 bytes: &#91;9fls8bwv]\/9fls8bwv\/6 bytes: &#91;zfjklzhm]\/zfjklzhm\/6 bytes: &#91;exeky1m2]\/exeky1m2\/6 bytes: &#91;mqi11o2o]\/mqi11o2o\/6 bytes: &#91;b7hzs0ip]\/b7hzs0ip\/6 bytes: &#91;2dt4wq9d]\/2dt4wq9d\n\/6 bytes: &#91;6sori6y4]\/00005 6sori6y4\/6 bytes: &#91;l4iv2qgr]\/l4iv2qgr\/6 bytes: &#91;9yc39f25]\/9yc39f25\/6 bytes: &#91;ijtan82p]\/ijtan82p\/6 bytes: &#91;u03ert1n]\/u03ert1n\/6 bytes: &#91;hf2cy6qf]\/hf2cy6qf\/6 bytes: &#91;o936snch]\/o936snch\/6 bytes: &#91;6pyqcy9t]\/6pyqcy9t\n\/6 bytes: &#91;d17dc4fh]\/00006 d17dc4fh\/6 bytes: &#91;1z2dtov8]\/1z2dtov8\/6 bytes: &#91;ncw5v2ry]\/ncw5v2ry\/6 bytes: &#91;lg90wern]\/lg90wern\/6 bytes: &#91;v8k27knh]\/v8k27knh\/6 bytes: &#91;i5gpv5rr]\/i5gpv5rr\/6 bytes: &#91;a401wuzc]\/a401wuzc\/6 bytes: &#91;qb872hiu]\/qb872hiu\n\/6 bytes: &#91;3e28gqkv]\/00007 3e28gqkv\/6 bytes: &#91;90gvp2pb]\/90gvp2pb\/6 bytes: &#91;wa449h7o]\/wa449h7o\/6 bytes: &#91;r0yo8qnw]\/r0yo8qnw\/6 bytes: &#91;ohettmrn]\/ohettmrn\/6 bytes: &#91;zkznxobg]\/zkznxobg\/6 bytes: &#91;o8tsp19w]\/o8tsp19w\/6 bytes: &#91;adlj1ab0]\/adlj1ab0\n\/6 bytes: &#91;33fwjh4v]\/00008 33fwjh4v\/6 bytes: &#91;m695umdx]\/m695umdx\/6 bytes: &#91;50bi59u0]\/50bi59u0\/6 bytes: &#91;cabcjlyh]\/cabcjlyh\/6 bytes: &#91;ont9hx9s]\/ont9hx9s\/6 bytes: &#91;m4olw55]\/0m4olw55\/6 bytes: &#91;wmegho9f]\/wmegho9f\/6 bytes: &#91;600aj7k5]\/600aj7k5\n\/6 bytes: &#91;d711s29h]\/00009 d711s29h\/6 bytes: &#91;8vcucf6y]\/8vcucf6y\/6 bytes: &#91;x2ekuqo8]\/x2ekuqo8\/6 bytes: &#91;msmqzwue]\/msmqzwue\/6 bytes: &#91;kgdm7xyw]\/kgdm7xyw\/6 bytes: &#91;rmeff22k]\/rmeff22k\/6 bytes: &#91;wa6xtfdw]\/wa6xtfdw\/6 bytes: &#91;lmhmb5ti]\/lmhmb5ti\n$ <\/code><\/pre>\n\n\n\n<p>Viel\u00e4 debukkauksessa k\u00e4ytetty rutiini, joka tulostaa long long:in ll base lukuj\u00e4rjestelm\u00e4ss\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void fprintfbase(FILE *fp1, unsigned long long ll2, int base) \/\/ JariK 2023\n{\n  int count;\n  unsigned long long ll, divider;\n\n  if(base == 2)\n    fprintf(fp1,\"0b\");\n  else if(base == 8)\n    fprintf(fp1,\"0o\");\n  else if(base == 10)\n    fprintf(fp1,\"0d\");\n  else if(base == 16)\n    fprintf(fp1,\"0x\");\n  \n  ll = ll2;\n  divider = 1;\n  count = 0;\n\n  for(;;) { \/\/ count digits\n    ll \/= base;\n    count++;\n    if(ll == 0)\n      break;\n    divider *= base; \/\/ do not count last digit\n  }\n\n  while(count &gt; 0) { \/\/ print digits\n    fprintf(fp1,\"%c\", basedigits&#91;(ll2 \/ divider) % base]);\n    divider \/= base;\n    count--;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty kentti\u00e4 ressu_nonrandom() rutiiniin. N\u00e4in pyrit\u00e4\u00e4n varmistamaan, ett\u00e4 eri prosessissa(getpid) ja eri kellonaikaan(tv.tc_sec ja tv.tv_usec) generoidut satunnaisluvut ovat varmasti erilaisia. Lis\u00e4ksi on lis\u00e4tty satunnaisuutta prosessin kuluttaman ajan lis\u00e4\u00e4misell\u00e4 (clock).<\/p>\n\n\n\n<p>Periaatteessa ressun p\u00e4\u00e4luuppi riitt\u00e4\u00e4 kelvollisiin satunnaislukuihin, mutta tapauksessa jossa koneen kellojono on liian s\u00e4\u00e4nn\u00f6llinen tarvitaan copy-reverse:n tuomaa lis\u00e4\u00e4. Se ett\u00e4 kellonaika tuodaan mukaan copy-reverse:en siirt\u00e4\u00e4 satunnaisuuden generoinnin uudelle tielle siin\u00e4 tapauksessa ett\u00e4 kello on asetettu. Tapauksessa, jossa kellonaikaa ei ole j\u00e4\u00e4d\u00e4\u00e4n kellojonon uniikkisuuden varaan. Jatkossa viel\u00e4 yksi testiajo, jossa tutkitaan kellojonon uniikkisuutta (newressutest16).<\/p>\n\n\n\n<p>T\u00e4h\u00e4n nonrandom:iin voisi viel\u00e4 lis\u00e4t\u00e4 prosessorin id:n yksil\u00f6im\u00e4\u00e4n konetta, mutta sellaista ei ole saatavilla (onneksi..). Toki sen voisi korvata prosessorin tekem\u00e4ll\u00e4 satunnaisluvulla (intel:in tapauksessa rdrand), mutta sit\u00e4 en kiistanalaisuuden vuoksi tehnyt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned int ressu_nonrandom() \/\/ not really random\n{\n  static unsigned int rando = 0;\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  rando = rando +\n    \/\/genbytes +\n    \/\/time(NULL) +\n    \/\/ressu_useconds() +\n    \/\/ressu_clock() +\n    \/\/buf.tms_utime + \n    \/\/buf.tms_stime +\n    getpid() +\n    clockbytes +\n    tv.tv_usec +\n    tv.tv_sec +\n    clock() \/ CLOCKS_PER_SEC +\n    clock() % CLOCKS_PER_SEC +\n    ch * ch;\n\n#ifdef DEBUG04\n  count&#91;rando % ressuct_bytes]++;\n#endif\n  \n#ifdef DEBUG2C\n  fprintf(stderr,\" %u\", rando % ressuct_bytes);\n  newressu_output = 1;\n#endif\n  \n  return(rando);\n}<\/code><\/pre>\n\n\n\n<p>Jo edellisess\u00e4 rutiinissa olevalla DEBUG04 osuudella on tarkoitus tarkastella nonrandom:in hajontaa puskurissa. Seuraavassa muut (ja edellinen) DEBUG04:n osat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>....\n#define DEBUG04 2\n\n#ifdef DEBUG04\n\nunsigned long count&#91;RESSUT_BYTES];\n\n#endif\n....\n#ifdef DEBUG04\n  count&#91;rando % ressuct_bytes]++;\n#endif\n....\n#ifdef DEBUG04\n\n  for(int c = 0; c &lt; RESSUT_BYTES; c++)\n    count&#91;c] = 0;\n\n#endif\n....\n#ifdef DEBUG04\n  int bufferlen = 0;\n  for(int c = 0; c &lt; ressuct_bytes; c++) {\n    unsigned char buffer&#91;16];\n    sprintf(buffer, \"%lu\", count&#91;c]);\n    if(bufferlen &lt; strlen(buffer))\n      bufferlen = strlen(buffer);\n  }\n  for(int c = 0; c &lt; ressuct_bytes; c++) {\n    if(c % 16 == 0) {\n      if(c &gt; 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%05u \", c);\n    }\n    fprintf(stdout,\"%*lu\", bufferlen + 1, count&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n#endif\n....<\/code><\/pre>\n\n\n\n<p>DEBUG04:n tulostaa seuraavan kaltaisen raportin: T\u00e4ll\u00e4 kertaa en tarkemmin tutkinut muuta kuin sen ett\u00e4 kaikkia puskurin merkkej\u00e4 k\u00e4ytet\u00e4\u00e4n tasaisesti.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu -l100000 --quiet\n00000  1005  956  956 1011  967  987  975 1039  981  998 1047 1022  982  943 1009  952\n00016   961 1061 1005  923 1014 1026 1020 1032  954  962  983  995 1000 1029  904  947\n00032   967  950 1011 1017 1019 1022  922 1005 1026 1002  976 1002  987  984 1005  980\n00048  1054  999  998  974  997  953  987 1028  977  947 1010  985  977  973  915  975\n00064   944 1042  940  954 1019  915 1003  968  988 1018  994  942 1005  974  973 1011\n00080   987  947 1009  937  987  973  956  940 1005  971  972 1004  988  921 1006 1040\n00096  1016  964 1008  982 1003  989 1010  988 1021 1005 1019  955  972  963  965  979\n00112   970  972 1039 1005  983 1008 1010  965  999 1044  969  939  994  961  986 1024\n00128   941  943 1019  950  999  934 1021  945 1035  978  951  945 1009  967 1019 1022\n00144   995  992  992  984 1025  989 1013 1037  970  989  986  997  993  994  930  980\n00160  1012  981  977 1013  993  980 1009  929 1017 1037  977  922  956 1068  974  976\n00176  1014  986  993  958 1010  975  989  970  933  985  980 1025  918  949 1034  923\n00192   974 1015  957  990  985  985  991  998 1034 1029  949  971 1030  997  991  946\n00208   961  988  986  960  950  985  980  950  969 1032 1011  982  940  965  989 1002\n00224  1067 1026  973  965 1001  989  987  951  964  971  951  954  929 1066  999  975\n00240   967 1025  928  989 1025  982  979 1002  943 1007  957 1010  965  990  950 1001\n00256   996 1019 1004  976 1062  953 1023 1043  956  991  966  997  963 1036  947  974\n00272   980  931  945  935 1013 1020  944  967  987 1018  977 1010  967  951  990  922\n00288  1015  976 1008  992  985  930  998  994  970  995 1067  994  949  997  987 1008\n00304  1030 1095 1034  997 1014 1064 1024 1029  988  948  988  970 1056 1035  983 1002\n00320   989  994  989 1007  995 1047  964  988 1014  975 1062 1016  992 1009  981  957\n00336  1000  960  992  963  951 1004  964  999 1000 1023  971  956  986  961 1015  980\n00352   989  982  971  959  968  980  923  974  994 1011 1006  994 1002 1008  954  974\n00368  1038  950  980  999  957  999  972  921 1012 1015 1042  984  988  970  960  989\n00384   987  958  978  956 1042 1051  967 1004  963  987  968  987 1001 1011 1013 1018\n00400   961 1023 1027  976  965  969  891 1010  941 1005  954 1046 1035  995 1003  961\n00416   995 1003 1017 1012 1028  970  980  973 1019  986  979 1006  976  998  994  952\n00432  1024  981  931  972  974  977  971 1008 1028  973 1011  977  977 1009  907  963\n00448  1017 1008  936  984  959  986 1036 1055  998 1087 1014  975  989  932  935 1063\n00464  1028 1021 1026 1006  988  961 1028  956  980  999  986  992  984 1003 1016  977\n00480   968  982 1034  981 1019  982  946  982  987  993  999  978  987 1034 1020 1052\n00496   969  989 1042  988  994 1022  991  926  967  963  942  994 1012 1010  948  967\n00512  1045 1029 1016  995  963  968 1001 1013  986 1008  977 1034  968 1010 1028  982\n00528   965 1036  984 1011  974 1013 1021  971 1015 1045  973  984  960  927 1045  994\n00544   946  961  974 1012 1018 1025  960  996  969  989 1019 1009  998 1008  944 1014\n00560   963  979 1015  981 1021  968  986  986  978 1000 1050  948  961  993  982  960\n00576  1025 1018 1008 1048  944  975 1013  936 1009  972 1007  960 1020 1017  997 1035\n00592   968 1000 1009  975 1006 1026  980 1018 1021  967  933  933  978  985 1008  985\n00608   991  940  942  945  995 1011  991  974 1016 1004  960  945 1005  953  999 1016\n00624  1050  996  984 1035  995  961 1011 1021 1001  984  981 1022  988  939  962 1003\n00640  1023  953  927  974  996  977  965 1009  964 1028  975 1059 1020  996 1017  965\n00656  1021 1001  939  988  982  999 1001 1005  959  961  953 1030  948  949  991  981\n00672   971  947  961  983 1030  951  962  968  968 1009  968  937  915  967 1009 1014\n00688   979 1000  921 1040  967 1039  989  951  957 1004  981  989  992 1013  891  946\n00704   956  995 1035  970 1000  992  962  999 1004  999  980 1060  994 1018  989 1007\n00720   971  983  991  977  942 1016 1011  918 1020  973  957  983  973 1022 1006  969\n00736  1004  994  983  930  975 1011  993  974  986  990 1027  996  998 1005  987 1006\n00752  1054  954  985  977  954 1027 1001 1026 1002 1011 1003  996  943  993  992  941\n00768  1036  954 1012  954 1001 1066  987 1006 1026  988  986 1055  937 1005  995 1000\n00784   993  952  962  983  975  937  977  989 1011 1006 1012  992 1024  933  980 1013\n00800   960  991  969  961 1017 1007  943  979  920 1055  973  962 1012  952  915 1008\n00816  1027  985 1022  989  950  977  974  987  973 1003  981  992  929 1015  965  971\n00832   994  983 1020  955 1024 1035  956 1055  990  957  932 1015 1013  996 1028 1002\n00848   953 1008  978  986  997  970  985 1014  979  957 1002 1011 1011  993  994  970\n00864   987  991 1035 1066  996  973  989  975  998  981 1052  983  934  960 1012  968\n00880   976  955  976 1032  969  920  959  929  987  969 1000  979  974  986  984  982\n00896  1026  910 1010 1054 1014  910 1009  967 1027  997  994  953  947 1035  984  959\n00912  1026  976 1000 1002 1008  975 1015  952  979 1008  957  944 1032 1040 1014  957\n00928  1045  999 1000 1004  963  960  979  957  992  953  991 1025  970  920  980  961\n00944   983  930  943  898 1000 1075 1049  960 1014 1051 1027  937 1018  975  977  964\n00960  1009  993 1019  986 1007  997  981  992  967 1000 1022  964  995  949  918  950\n00976  1017 1017  957  973  981  896  979  975 1002  998  970  990 1044 1002 1018  970\n00992   969 1003  980  970 1002  982 1012 1045  985  996  991 1026  998 1046  924  992\n01008  1026 1009  976  936  987 1008  977  985 1021  999 1017  985 1075 1041  953  978\n01024   947 1011  955  978  954  947  947  985 1020 1007 1005  983 1002  975  954  922\n01040  1034  995 1017  950 1030  989  974  945  932  992  969 1005  993  932  940  985\n01056  1009  989  957  934 1019 1043  991  980  938  993 1004 1003  962  955 1000  949\n01072   946  947 1005  979 1019 1008 1039  985 1031  971  973  943  929  957  950 1041\n01088   964  973 1025  994  952  929  967 1040 1019 1015 1052  959 1018 1021  943 1013\n01104   911 1020  999  998  947 1004  964  952  956  998 1012  997  964  984 1013  984\n01120   930 1003  973  946  977 1007  940 1062  928 1012 1009  995 1000 1007  999  983\n01136   952 1017  961  954  937 1013  983  993  956  931 1063  944  974 1066 1015 1003\n01152   990  973 1009  965  960 1020  978  986 1039  971  970  983 1004  989  958  940\n01168   994 1009  948  974  995  911 1013 1021  973 1037  994 1021  998  968  997  964\n01184  1018 1010 1025  964 1013  957  970 1028  994 1012 1014  937  983 1016 1006 1015\n01200   977  961  971 1034  954  976 1034  994  990  963  947 1024  996 1044  935  965\n01216  1013  984  971  997 1023 1032 1023  949  962 1050  997  992  958  982  948 1011\n01232  1008  973  973  997  893 1003  997 1010  931  979  950  979  964  957  953  970\n01248   959  980  922  980  996  965  963  948  945 1014 1054 1034  971  948 1002  964\n01264  1077 1038  989  966  952  951 1027  947 1032  980  993 1034  979  953 1026  988\n01280  1022  975 1004 1003 1016  964  985  986 1009 1008 1018  990 1058  936 1000  994\n01296  1038 1014  941  927 1046  963 1055  954  950 1042  991 1014  956 1012 1006 1038\n01312   965  992 1041  998 1022  965  905  944  950 1003  973  973 1053  964 1018  988\n01328   990 1000  985  982  972  974 1015 1007  964  963  967  989  950  994  985  974\n01344  1027 1026  950 1018 1017  991  963  961 1027  970  938  998  925 1024  973 1004\n01360   996  955 1018  972  991  971 1016  993  962  998 1044  991  990 1008  987  947\n01376  1002 1028  942  983  982  961 1003 1039  978 1007 1032  961  981  966  987 1050\n01392   930  966  967 1006 1040 1000  990  978  946  931 1000  960  977 1019  960  980\n01408   937 1023 1027 1051 1015  983 1008  949  951  956  961  977  993  986  951  930\n01424  1024  999  979 1046  952  943  973 1054  987  995 1009  985 1028  945  992  963\n01440  1031  967  999  989 1020  966  937  959 1034  952 1010 1023  961 1015  963 1011\n01456  1026 1035 1051  963  937  924  973  959 1028  997 1048 1053  987  913  926 1026\n01472   953  964  975  986  919  962 1012  995  952 1056  970 1002 1032  994  889  960\n01488   948  910  992 1017  955  988 1002 1020  891 1027 1000  962  989 1017 1010 1045\n01504  1033 1021  960 1014  973  988 1038  990 1023  986  987  961  936 1003  952 1001\n01520   999  908 1026  976  989  971  964  986 1008 1040  957  971  954  991  968  979\n01536  1001  948 1005  976  975  999 1017  930  999 1006 1028  982  994  986  949 1028\n01552  1022 1000  923  956 1014  934 1068 1013  985  963  959 1014  927  984 1064 1074\n01568   952 1010 1035 1033  995  929  976  985  984  983  984  951  992  994  994 1003\n01584   946 1024  978 1059  962 1008 1023  943  982  984  978 1028 1025  978  960  929\n01600   999 1030 1023  992 1006 1024  979  965 1028  958 1037  997  972  972 1056  929\n01616  1025  995 1006 1004  993  991  953  970  985  955 1020 1024  972  949  968  972\n01632   978  983 1026 1041 1000 1021 1013  985 1009  937  980  902  997  940  988  988\n01648   991  974 1037  974  982  966  983  963  976  987  953 1015  990  992  964 1045\n01664   954  960  941 1004 1034  995 1010  952 1015  955  985 1000 1012 1019  949 1045\n01680   971  998 1016 1008  969  965  951  916  958  996  954 1035  968  955  955  970\n01696  1023  982 1004  986  993  964 1000  966 1024  959  939  954  976  948 1011 1020\n01712   964  972 1000  954 1002  971  963  997  964 1012  959 1008  963  991 1005  957\n01728  1015  955  998  932 1044  948  975 1006 1000 1032  964  972  950  948  960 1045\n01744  1022  990  957  970  991  985  954 1016  919  939 1014  957  933  971 1039  982\n01760   989  991  910  997 1033 1036  969 1016  951 1016  981  967  982  942  960  959\n01776  1015 1026 1007  995 1006  957 1023  968 1068  990  972  978  908  979  982  944\n01792  1038 1036  984  990  974  987  968  970  974 1038  979  936  930  957  962 1014\n01808  1011  968  992 1039  959 1042  933  987 1046 1008 1009 1017  988 1040  941 1023\n01824   979  982  970 1019  959  945  976 1019 1045 1041  956  953 1029  986  930  981\n01840   982  959  991  979  952 1015  963  993 1014 1015  989  966 1037  975 1003 1005\n01856   994  997  969  953  962  999  923  989  970  903  983 1053  907  972 1047 1013\n01872   987 1041  968  963  979 1019 1002 1061 1008 1015  989 1027 1042  910  954  971\n01888   941  979  995 1059 1036  993  967 1000  937  967  945 1035 1011  904  923  960\n01904  1007 1016  983 1035  977  959  982  941  930  942 1000  921  947 1026  958 1016\n01920   966  996 1082  931  990  933 1016 1037  979  967 1042 1009  952  980 1015 1002\n01936   963  962  966 1014  947  976 1003  965 1005 1046  974  973 1078  924  983 1027\n01952   991  971  968 1015  916 1032  994  990 1021 1001  972 1033  987 1040 1015  987\n01968   932 1061  979  948 1016  978  947  892 1019 1015 1026  997  994  968  958  990\n01984   928  962 1011 1043  966 1023  978 1058  943 1007 1009 1019  974  995  969  974\n02000   935 1023 1028  998  985  993 1032  958 1006 1017  950  986  992  983 1000  910\n02016  1038 1025 1008  971  900  926  983 1001  943  954  974 1002  997 1051  976 1002\n02032  1010  989  950  991 1022  985  957 1008  972  955  930 1004  994  981  946  958<\/code><\/pre>\n\n\n\n<p>Seuraavassa viel\u00e4 kellojonon uniikkiuden tarkasteluun pieni ohjelma. Ohjelma pakkaa kellojonon siten ett\u00e4 yhdest\u00e4 ketjusta tulostetaan aina per\u00e4kk\u00e4in arvo ja pituus. Seuraavassa esimerkkitietue: raportin luvut ovat kaksimerkkisi\u00e4 heksalukuja. Ensimm\u00e4inen merkki on nolla ja niit\u00e4 on $5 kappaletta, seuraava merkki on $1 ja niit\u00e4 on $1 kappale, jne&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest16 --filesize1600 -\nstring:'1600', base:10(10B), multiplier:1(1B), prevll:1600(~1K), ll:1600(~1K), totll:1600(~1K)\nclockstream, lines:1(1B), clocksize:1600(~1K), linesize:1601(~1K), filesize:1601(~1K)\nfilename:-\n00050101020103080411051106130714081309110a140b140c130d140e130f141014110f121113131414151416141714181419121a131b141c141d141e141f1420142112221423142414251426142714281429122a142b132c142d142e142f1430143113321333133414351436143714381439123a133b143c143d133e143f1440144111421443144413451446144714481349124a134b144c144d144e144f1350145113521453145413551456145714581359135a135b145c135d145e145f1360146111621363146413651466136714681469126a136b136c146d146e136f1470147112721473137414751376147714781379127a137b137c147d137e147f1380138113821283138413851486138714881389128a138b138c148d108e148f1390149112921393149413951496139714981399129a139b139c149d139e139f14a013a111a212a313a413a513a614a713a813a912aa12ab14ac13ad13ae13af14b013b112b214b313b413b513b613b714b813b911ba13bb13bc13bd14be13bf13c013c112c213c312c413c513c613c713c813c912ca12cb13cc13cd13ce13cf13d013d111d213d313d413d513d614d713d813d911da12db13dc13dd13de13df13e013e111e213e313e413e513e613e713e813e911ea12eb13ec12ed13ee14ef12f013f113f212f313f413f512f614f712f813f911fa13fb13fc13fd13fe13ff130013010c020f03110411051206130712081209100a120b120c120d120e130f1210121111121313131412151316131712181319101a111b121c121d131e131f1320132110221223122412251326132713281329102a112b112c122d132e132f1230133111321233133413351336123713381339103a133b113c133d123e133f1240134111421143124412451346134713481249104a124b134c124d134e134f1350125111521353135412551356125713581259115a125b135c125d135e135f126013610f620e63126411651266126713681269116a116b126c126d136e126f1370127112721273137412751376127713781279107a117b137c127d127e137f1280138110821183118412851286128713881289118a118b128c138d128e128f13\n.\/newressutest16: hashed file, sha256:661922921ecb992b816a89aa619fbb639b215104b51a4b3f3531ca7cb45362a3\njarik@jarik-HP14dv2002:~\/f\/ressurngd$ \n<\/code><\/pre>\n\n\n\n<p>Seuraavassa ohjelmaa on ajettu siten, ett\u00e4 sen tuloste lajitellaan ja vertaillaan 1500 ensimm\u00e4ist\u00e4 merkki\u00e4 lajitellun tiedoston per\u00e4kk\u00e4isist\u00e4 riveist\u00e4. Jos ne ovat samat, se on ongelma ja tietueet tulostetaan. Jos ne poikkeavat, ne ovat molemmat uniikkeja, eik\u00e4 mit\u00e4\u00e4n tulosteta: Eli kaikki on kunnossa, jos ohjelma ei tulosta mit\u00e4\u00e4n.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressutest16 --filesize100g --stdout | sort | uniq -D --check-chars=1500\nstring:'100g', base:10(10B), multiplier:1073741824(1G), prevll:100(100B), ll:107374182400(100G), totll:107374182400(100G)\nclockstream, lines:67066948(~63M), clocksize:1600(~1K), linesize:1601(~1K), filesize:107374183748(~100G)\nfilename:-\nDone:100.0%  \n.\/newressutest16: hashed file, sha256:485573cfe61b732c01722be1cddfd12adf769055e0395f89baad0ad6aa62857a\n$<\/code><\/pre>\n\n\n\n<p>Ja varsinainen ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;math.h&gt;\n#include &lt;ctype.h&gt;\n\n#include \"sha256.h\"\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressutest16 version 0.2 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2024 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FILESIZE 16010\n#define CLOCKSIZE 1600 \/\/ bytes per line\n#define LINESIZE 1601 \/\/ CLOCKSIZE + 1\n#define LINES 10\n#define BLOCKSIZE 1024\n\n#define GENT_SIZE 128\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\n#include &lt;sys\/time.h&gt;\n\nunsigned long long useconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec + 1000000 * tv.tv_sec);\n}\n\n#include &lt;string.h&gt;\n#include &lt;stdlib.h&gt;\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nint stat = 0;\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p)\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p &gt; 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p &gt; 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p) \/\/ JariK 2023\n{\n  int digit;\n  \n  if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2)\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n\n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll &gt;= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\n#define DEBUG45 2\n\nunsigned long long getlonglong(unsigned char *p2) \/\/ JariK 2023\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value:%d\", digit);\n      fprintf(stderr,\", base:%u(\", base);\n      readablelonglong(stderr, base);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", ll:%llu(\", prevll);\n      readablelonglong(stderr, prevll);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\", multiplier:%llu(\", multiplier);\n      readablelonglong(stderr, multiplier);\n      fprintf(stderr,\")\");\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n      exit(1);\n\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG45\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%u(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value:%d\", digit);\n    fprintf(stderr,\", base:%u(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  return(totll);\n}\n\n#define FILE_HASH 2 \/\/ on by default\n\n#ifdef FILE_HASH\n\nvoid hashfinal2string(unsigned char *hashstring, unsigned char *final)\n{\n  for(int c = 0; c &lt; HashLen; c++) {\n    sprintf(hashstring + 2 * c, \"%02x\", final&#91;c]);\n  }\n}\n\n#endif\n\n#define DEBUG79 2\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d, percentageline = 1, prevpros, pros, quiet = 0, help = 0;\n  int filesize_set = 0, clocksize_set = 0, linesize_set = 0, lines_set = 0;\n  unsigned long long filesize = FILESIZE, lines = LINES;\n  unsigned int clocksize = CLOCKSIZE, linesize = LINESIZE;\n  int stdoutflag = 0;\n  unsigned long long plines = 0;\n  unsigned char *buffer, filename&#91;128] = \"\";\n  FILE *fp1;\n  \n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n\n  for(c = 1; c &lt; argc; c++) {\n\n    if(c == argc - 1 &amp;&amp; !strcmp(argv&#91;c], \"-\")) { \/\/ last option hyphen\n      stdoutflag = 1; \/\/ output to stdout\n      continue;\n    }\n    \n    if(strncmp(\"-\", argv&#91;c], 1)) { \/\/ filename not expected\n      fprintf(stderr,\"%s: filename not expected\", procname);\n      fprintf(stderr,\", parameter:%s\", argv&#91;c]);\n      fprintf(stderr,\"\\n\");\n      exit(1);\n    }\n    \n    if(!strncmp(\"-\", argv&#91;c], 1)) { \/\/ option starting with hyphen\n      \n      if(!strncmp(\"-o\", argv&#91;c], 2)) { \/\/ output filename\n\tif(*(argv&#91;c] + 2) != '\\0') {\n\t  strncpy(filename, argv&#91;c] + 2, sizeof(filename));\n\t} else if(c + 1 &lt; argc) {\n\t  strncpy(filename, argv&#91;c + 1], sizeof(filename));\n\t  c++;\n\t}\n\tstdoutflag = 0;\n\t\n      } else if(!strcmp(\"--stdout\", argv&#91;c])) { \/\/ output stdout\n\tstdoutflag = 1; \/\/ output to stdout\n\tfilename&#91;0] = '\\0';\n\t\n      } else if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c]) ) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--quiet\", argv&#91;c])) {\n\tquiet = !quiet;\n\n      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--linesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  linesize = getlonglong(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  linesize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlinesize_set = 1;\n\t\n      } else if(!strncmp(\"--lines\", argv&#91;c], 7)) {\n\tif(*(argv&#91;c] + 7) != '\\0') {\n\t  lines = getlonglong(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  lines = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tlines_set = 1;\n\n      } else if(!strncmp(\"--clocksize\", argv&#91;c], 11)) {\n\tif(*(argv&#91;c] + 11) != '\\0') {\n\t  clocksize = getlonglong(argv&#91;c] + 11);\n\t} else if(c + 1 &lt; argc) {\n\t  clocksize = getlonglong(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tclocksize_set = 1;\n\n      } else if(!strcmp(\"--stat\", argv&#91;c])) {\n\tstat = !stat;\n\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    }\n  }\n\n  if(!linesize_set)\n    linesize = clocksize + 1;\n  else if(!clocksize_set)\n    clocksize = linesize - 1;\n\n  if(!filesize_set)\n    filesize = lines * linesize;\n  else if(!lines_set) {\n    lines = (filesize + linesize - 1) \/ linesize; \/\/ round up\n    filesize = lines * linesize;\n  } else if(!linesize_set) {\n    linesize = (filesize + lines - 1) \/ lines; \/\/ round up\n    clocksize = (linesize - 1);\n    filesize = lines * linesize;\n  }\n\n  if(linesize != clocksize + 1 ||\n     linesize &lt; 5 || clocksize &lt; 4) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", clocksize:%u(\", clocksize);\n    readablelonglong(stderr, clocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize != lines * linesize ||\n     lines &lt; 1 || linesize &lt; 5) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: mismatched parameters\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  if(filesize \/ lines != linesize) { \/\/ test overflow too\n    fflush(stdout);\n    fprintf(stderr,\"%s: parameter overflow\", procname);\n    fprintf(stderr,\", lines:%llu(\", lines);\n    readablelonglong(stderr, lines);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", linesize:%u(\", linesize);\n    readablelonglong(stderr, linesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n  \/\/ print help message if needed\n  \n  if(help) {\n    fprintf(stderr,\"%s\", procname);\n    fprintf(stderr,\"\\n\\t&#91;-o filename]\");\n    \/\/fprintf(stderr,\" &#91;--stdout]\");\n    fprintf(stderr,\"\\n\\t&#91;--filesize base-number-multiplier]\"); \n    fprintf(stderr,\"\\n\\t&#91;--lines base-number-multiplier]\");\n    fprintf(stderr,\" &#91;--linesize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--clocksize base-number-multiplier]\");\n    fprintf(stderr,\"\\n\\t&#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--stat]\");\n    fprintf(stderr,\" &#91;--verbose]\");\n    fprintf(stderr,\" &#91;--quiet]\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Examples:\\n\");\n    fprintf(stderr,\"\\t$ %s --single --filesize1g\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --lines1m\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --linesize25\\n\", procname);\n    fprintf(stderr,\"\\t$ %s --single --filesize1g --clocksize12\\n\", procname);\n    exit(1);\n  } \/\/ end of if(help)\n\n#ifdef DEBUG79\n\n  \/\/ print filesize parameters\n  \n  fprintf(stderr,\"clockstream\");\n  fprintf(stderr,\", lines:%llu(\", lines);\n  readablelonglong(stderr, lines);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", clocksize:%u(\", clocksize);\n  readablelonglong(stderr, clocksize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", linesize:%u(\", linesize);\n  readablelonglong(stderr, linesize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n  \n#endif\n  \n  if(!stdoutflag &amp;&amp; filename&#91;0] == '\\0') {\n\n    \/\/ find first available filename,\n    \/\/ or empty \"slot\"\n\n    for(c = 1; c &lt;= 99999; c++) {\n      sprintf(filename, \"newressutest16.%d.rnd\", c);\n      if((fp1 = fopen(filename, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n\n#ifdef FILE_HASH\n      unsigned char filename2&#91;138];\n      sprintf(filename2,\"%s.sha256\", filename);\n      if((fp1 = fopen(filename2, \"r\")) != NULL) {\n\tfclose(fp1);\n\tcontinue;\n      }\n#endif\n\n      break;\n    }\n  }\n\n  if(stdoutflag) {\n    if(isatty(STDOUT_FILENO)) { \/\/ 0=stdin, 1=stdout, 2=stderr\n      percentageline = 0;\n    }\n  }\n    \n  if(stdoutflag) \n    fprintf(stderr,\"filename:-\\n\");\n  else\n    fprintf(stderr,\"filename:%s\\n\", filename);\n    \n  if(stdoutflag == 1) {\n    fp1 = stdout;\n  } else if((fp1 = fopen(filename, \"w\")) == NULL) {\n    fprintf(stderr,\"%s: cannot open file\", procname);\n    fprintf(stderr,\", filename:%s\", filename);\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  }\n  \n#ifdef FILE_HASH\n  \n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n\n  HashInit(&amp;hash); \/\/ initialize hash\n\n#endif\n  \n  if((buffer = malloc(linesize + 1)) == NULL) { \/\/ space for '\\0' too\n    fprintf(stderr,\"%s: cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n  }\n\n  memset(buffer, 0, linesize + 1);\n\n  prevpros = -1;\n  \n  int count, prevusec = -1, usec;\n  unsigned long long diff0;\n\n  for(;;) {\n\n#define DEBUG87\n\n#ifdef DEBUG87\n    prevusec = useconds();\n    while((usec = useconds()) == prevusec);\n    diff0 = usec;\n#else\n    diff0 = 0;\n#endif\n    *buffer = '\\0';\n    \n    count = 0;\n    prevusec = -1;\n    \n    for(;;) {\n      usec = (useconds() - diff0) &amp; 0xff;\n      if(prevusec == -1)\n\tprevusec = usec;\n      else if(usec != prevusec) {\n\tunsigned char buffer10&#91;10];\n\tsprintf(buffer10,\"%02x%02x\", prevusec, count);\n\tif(strlen(buffer) + strlen(buffer10) &lt; linesize)\n\t  strcat(buffer, buffer10);\n\telse\n\t  break;\n\tprevusec = usec;\n\tcount = 0;\n      }\n      count++;\n    }\n    strcat(buffer, \"\\n\");\n    \n#ifdef FILE_HASH\n    HashUpdate(&amp;hash, buffer, strlen(buffer)); \/\/ calculate hash\n#endif\n      \n    if(fwrite(buffer, 1, strlen(buffer), fp1) &lt; strlen(buffer)) {\n      fprintf(stderr,\"%s:\", procname);\n      fprintf(stderr,\" cannot write file\");\n      fprintf(stderr,\"\\n\");\n      exit(1);      \n    }\n    \n    plines++;\n    if(plines &gt;= lines)\n      break;\n\n  }\n\n#ifdef FILE_HASH\n  HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n  \n  if(!stdoutflag)\n    fclose(fp1);\n  \n#ifdef FILE_HASH\n\n  unsigned char hashstring&#91;2 * HashLen + 1];\n  \n  hashfinal2string(hashstring, digest);\n  \n  fprintf(stderr,\"%s: hashed file\", procname);\n\n  if(filename&#91;0] != '\\0') {\n    fprintf(stderr,\", filename:%s\", filename);\n\n    unsigned char filename2&#91;138];\n\n    sprintf(filename2,\"%s.sha256\", filename);\n\n    fprintf(stderr,\", hashfilename:%s\", filename2);\n\n    if((fp1 = fopen(filename2, \"w\")) != NULL) {\n      fprintf(fp1,\"%s\\n\", hashstring);\n      fclose(fp1);\n    }\n  } \/\/ end of if(filename&#91;0] != '\\0'\n  \n  fprintf(stderr,\", sha256:%s\\n\", hashstring);\n\n  if(!stdoutflag) {\n    fprintf(stderr,\"%s: checking sha256\", procname);\n    fprintf(stderr,\", filename:%s\\n\", filename);\n    unsigned char command&#91;1024];\n    sprintf(command,\"sha256sum %s\", filename);\n    system(command);\n  }\n  \n#endif\n  \n  free(buffer);\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>Copy-reverse on uudelleenkirjoitettu siten, ett\u00e4 kellojonoon lis\u00e4t\u00e4\u00e4n aikaista enemm\u00e4n satunnaisuutta: Uudessa versiossa on nelj\u00e4 (DEPTH) tasoa, joissa kussakin on oma lohkoihin jako. N\u00e4in ennen copy reverse k\u00e4sitteli kellojonon vain yhten\u00e4 copy reverse puskurina ja nyt niit\u00e4 on nelj\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEPTH 4\n\nunsigned int copyreverse = 1;\nunsigned long cblocks = 0;\nunsigned char lens = 4;\n\nstatic unsigned char ressu_copyreverse(int depth)\n{\n  static int reverse&#91;DEPTH] = {0}; \/\/ 0 = copy, 1 = reverse, 28.10.2022 JariK\n  static unsigned int len&#91;DEPTH] = {0};\n  static unsigned int count&#91;DEPTH] = {0};\n  static unsigned int low&#91;DEPTH] = {0};\n  static unsigned int high&#91;DEPTH] = {0};\n  static unsigned char bytes&#91;DEPTH]&#91;257] = {0};\n  \n  if(depth == 0) {\n#ifdef DEBUG2D\n    int c = ressu_clock();\n    fprintf(stdout,\", ch2:%02x\",c);\n    return(c);\n#else\n    return(ressu_clock());\n#endif\n  }\n\n  depth--;\n\n  \/\/ dividing clock stream into blocks\n  \/\/ and reversing every other block\n\n  \/\/ copy next block to bytes\n  \n  if(count&#91;depth] == 0) { \/\/ previous block ended\n    reverse&#91;depth] = !reverse&#91;depth];\n    len&#91;depth] = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 2; \/\/ block size\n    \/\/len&#91;depth] = (ressuct&#91;ressu_nonrandom() % ressuct_bytes] &amp; 3 ) + 2; \/\/ block size\n    \/\/len&#91;depth] = --lens + 2; \/\/ block size\n    \/\/len&#91;depth] = lens++ + 2; \/\/ block size\n    count&#91;depth] = len&#91;depth];\n    low&#91;depth] = 0;\n    high&#91;depth] = len&#91;depth];\n    rndbits2 += 2;\n#ifdef DEBUG2A\n    fprintf(stdout,\"\\nblk:\");\n    fprintf(stdout,\" depth:%d\", depth);\n    fprintf(stdout,\", reverse:%d\", reverse&#91;depth]);\n    fprintf(stdout,\", len:%d\", len&#91;depth]);\n    fprintf(stdout,\", count:%d\", count&#91;depth]);\n    fprintf(stdout,\", low:%d\", low&#91;depth]);\n    fprintf(stdout,\", high:%d\", high&#91;depth]);\n    fflush(stdout);\n#endif\n    for(int c = 0; c &lt; len&#91;depth]; c++) {\n      bytes&#91;depth]&#91;c] = ressu_copyreverse(depth); \/\/ block bytes\n#ifdef DEBUG2A\n      fprintf(stdout,\", b%d:%02x\", depth, bytes&#91;depth]&#91;c]);\n      newressu_output = 1;\n#endif\n    }\n  }\n  if(reverse&#91;depth]) { \/\/ reverse\n    \n    \/\/ get reversed byte to return\n    ch = bytes&#91;depth]&#91;--high&#91;depth]]; \/\/ reverse\n#ifdef DEBUG2E\n    fprintf(stdout,\", rev%d:%02x\", depth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;depth];\n\n  } else { \/\/ copy\n    \n    \/\/ get copied byte to return\n    ch = bytes&#91;depth]&#91;low&#91;depth]++];\n#ifdef DEBUG2E\n    fprintf(stdout,\", copy%d:%02x\", depth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;depth];\n  }\n\n  return(ch);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini kutsuu edellist\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  if(copyreverse) {\n    ch = ressu_copyreverse(DEPTH);\n  } else {\n    ch = ressu_clock();\n  } \/\/ end of if(copyreverse)\n\n#ifdef DEBUG2F\n  static unsigned int cols = 0;\n  if(cols % 32 == 0) {\n    if(cols &gt; 0)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%05u \",cols);\n  }\n  if(cols % 4 == 0)\n    fprintf(stdout,\" \");\n  fprintf(stdout,\"%02x\",ch);\n  cols++;\n#endif\n  \n  \/\/ statistics for theoretical\n  \/\/ random bits calculation (rndbits?)\n  \n  static int prevbyte = -1, clockcount = 0;\n  \n  if(prevbyte == -1)\n    prevbyte = ch;\n  if(prevbyte != ch) {\n    periods&#91;clockcount]++;\n    clockbytes += clockcount;\n#ifdef DEBUG2B\n    fprintf(stdout,\" %d\", clockcount);\n    newressu_output = 1;\n#endif\n    clockcount = 0;\n    prevbyte = ch;\n  }\n  clockcount++;\n  \n  return(ch);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty heprean (hebrew, &#8211;heb) merkist\u00f6:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--heb\", argv&#91;c])) { \/\/ hebrew\n\n\t\/\/ \u0590\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059a\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05c4\u05c5\u05c6\u05c7\u05c8\u05c9\u05ca\u05cb\u05cc\u05cd\u05ce\u05cf\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05eb\u05ec\u05ed\u05ee\u05ef\u05f0\u05f1\u05f2\u05f3\u05f4\u05f5\u05f6\u05f7\u05f8\u05f9\u05fa\u05fb\u05fc\u05fd\u05fe\u05ff\n\t\n\tdigits = \"\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      }<\/code><\/pre>\n\n\n\n<p>Seuraavassa satunnaisbittej\u00e4 heprean merkist\u00f6ll\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --heb\n00000 \u05e5\u05de\u05d7\u05d1\u05e1\u05e5\u05d3\u05e8\u05e2\u05e4\u05d9\u05e8\u05e7\u05db\u05d0\u05d8\u05d9\u05dc\u05d8\u05ea\u05e4\u05d5\u05d2\u05d2\u05d9\u05ea\u05d7\u05e1\u05e0\u05e1\u05e2\u05d9\u05e1\u05d2\u05ea\u05d6\u05e6\u05d5\u05e1\u05dc\u05e4\u05e1\u05dc\u05e0\u05e4\u05d9\u05e5\u05de\u05e7\u05d9\u05dc\u05d3\u05e5\u05e7\u05e2\u05e1\u05de\u05d6\u05d0\u05e4\u05e1\u05e5\u05e8\u05ea\n00001 \u05e3\u05ea\u05d7\u05d8\u05d9\u05d9\u05e2\u05d9\u05dd\u05ea\u05ea\u05d0\u05de\u05db\u05d6\u05e6\u05dd\u05e4\u05dd\u05d8\u05d8\u05dd\u05e5\u05e2\u05e7\u05e8\u05d2\u05d8\u05d6\u05e4\u05d7\u05e9\u05d0\u05e6\u05e0\u05de\u05e2\u05d1\u05d5\u05d7\u05e0\u05e5\u05d5\u05d8\u05d0\u05e3\u05e5\u05e4\u05e8\u05e7\u05d1\u05e2\u05d8\u05e9\u05ea\u05d8\u05d5\u05e0\u05e8\u05d4\u05e3\u05d6\u05e1\u05dc\n00002 \u05d6\u05dc\u05e2\u05d8\u05e3\u05dc\u05e3\u05d1\u05db\u05d2\u05d9\u05e4\u05dd\u05e7\u05e6\u05da\u05d8\u05e9\u05e1\u05d7\u05ea\u05e0\u05d6\u05db\u05e1\u05d4\u05e4\u05e4\u05d5\u05e6\u05e7\u05d3\u05e7\u05d9\u05d6\u05e4\u05d7\u05d4\u05e4\u05e3\u05ea\u05de\u05d8\u05da\u05e6\u05e4\u05d9\u05d6\u05d0\u05e7\u05e6\u05ea\u05d3\u05de\u05d1\u05d3\u05e6\u05e4\u05de\u05df\u05d6\u05e5\u05d7\u05d3\n00003 \u05e0\u05de\u05d5\u05d7\u05d0\u05dc\u05e9\u05e7\u05d1\u05da\u05db\u05d6\u05d3\u05e6\u05d7\u05e7\u05e7\u05e3\u05d1\u05e2\u05e8\u05e1\u05ea\u05e2\u05e7\u05e5\u05e1\u05e0\u05db\u05e4\u05dc\u05e3\u05ea\u05e5\u05da\u05d4\u05df\u05db\u05d4\u05e4\u05d2\u05e2\u05e4\u05e5\u05e4\u05e3\u05ea\u05d0\u05e0\u05d5\u05e2\u05ea\u05d1\u05d9\u05d1\u05dd\u05d5\u05d4\u05e2\u05e9\u05e4\u05dc\u05e4\u05e9\n00004 \u05d0\u05d0\u05e0\u05da\u05d7\u05e2\u05d7\u05dc\u05e3\u05e1\u05db\u05e4\u05d3\u05d2\u05d6\u05e9\u05e6\u05d3\u05d8\u05e6\u05e2\u05d7\u05e3\u05e5\u05da\u05dc\u05e2\u05d2\u05dd\u05dc\u05e9\u05d3\u05e1\u05d2\u05e1\u05d1\u05e3\u05e7\u05d9\u05e9\u05e7\u05d3\u05e2\u05e8\u05e5\u05e0\u05e5\u05d6\u05e2\u05d8\u05d9\u05d3\u05e4\u05df\u05d9\u05d4\u05df\u05d1\u05dd\u05d3\u05d1\u05da\u05d8\u05e6\n00005 \u05d9\u05e5\u05df\u05e3\u05e4\u05e8\u05e0\u05db\u05dc\u05de\u05d9\u05e9\u05dc\u05d3\u05ea\u05db\u05e9\u05da\u05d5\u05e7\u05e5\u05d6\u05e9\u05d8\u05df\u05da\u05d0\u05da\u05d3\u05db\u05d7\u05de\u05d0\u05df\u05de\u05db\u05d3\u05db\u05ea\u05e4\u05e5\u05db\u05e3\u05d9\u05d9\u05da\u05d6\u05df\u05e6\u05d4\u05e6\u05e4\u05d1\u05e6\u05d5\u05ea\u05d2\u05e8\u05d7\u05e6\u05e3\u05e7\u05d8\u05d6\n00006 \u05df\u05e0\u05ea\u05ea\u05d3\u05d1\u05e6\u05d3\u05d3\u05dc\u05dd\u05df\u05d2\u05e8\u05db\u05db\u05de\u05de\u05d6\u05d0\u05d5\u05d9\u05d2\u05d7\u05d9\u05d3\u05e4\u05d6\u05e2\u05e9\u05dc\u05e1\u05dc\u05d0\u05ea\u05d5\u05d6\u05d5\u05df\u05ea\u05ea\u05e3\u05d9\u05e6\u05e1\u05d3\u05e5\u05e2\u05e1\u05d1\u05e1\u05dd\u05e3\u05dd\u05e1\u05d7\u05e7\u05dd\u05e6\u05e4\u05e2\u05df\u05e7\u05e8\n00007 \u05e8\u05d5\u05df\u05d6\u05dd\u05e5\u05e0\u05d7\u05dd\u05e1\u05de\u05dd\u05d8\u05de\u05d3\u05ea\u05e0\u05e5\u05d4\u05e4\u05e4\u05d9\u05e1\u05e9\u05ea\u05d9\u05ea\u05d7\u05de\u05d2\u05e4\u05de\u05d2\u05d0\u05d5\u05e5\u05ea\u05e3\u05d7\u05d0\u05d4\u05e2\u05e3\u05d3\u05d7\u05df\u05d3\u05e6\u05ea\u05e4\u05db\u05da\u05e6\u05e0\u05e3\u05de\u05d7\u05d2\u05e9\u05e7\u05e0\u05de\u05e4\u05db\n00008 \u05d8\u05d8\u05e4\u05d6\u05e6\u05e0\u05ea\u05e8\u05de\u05d1\u05ea\u05e8\u05e0\u05df\u05e3\u05e1\u05d2\u05df\u05d4\u05e4\u05d0\u05d6\u05e4\u05ea\u05e8\u05ea\u05e9\u05d7\u05e6\u05d7\u05d1\u05d0\u05e4\u05d3\u05df\u05e0\u05db\u05d8\u05e9\u05e4\u05e2\u05df\u05d5\u05e7\u05d0\u05d7\u05d5\u05df\u05e0\u05e6\u05db\u05d7\u05d3\u05e4\u05d4\u05d2\u05d6\u05e0\u05e2\u05da\u05d1\u05d2\u05e8\u05e0\n00009 \u05da\u05db\u05d3\u05d7\u05e2\u05d2\u05e7\u05e3\u05ea\u05e6\u05e4\u05da\u05d8\u05e7\u05e4\u05e9\u05db\u05d4\u05dd\u05d3\u05e3\u05ea\u05e9\u05d7\u05df\u05d8\u05dc\u05d5\u05e3\u05e7\u05db\u05d6\u05d9\u05da\u05e4\u05e9\u05d0\u05e5\u05e9\u05df\u05ea\u05dc\u05df\u05e5\u05e7\u05d9\u05d1\u05e1\u05d5\u05de\u05db\u05e5\u05d5\u05d7\u05da\u05dd\u05d4\u05e1\u05d1\u05d6\u05de\u05d2\u05e6\u05df\n$<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty satunnaisbitit foinikialaisen (phoenician, &#8211;pho) merkist\u00f6n mukaan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --pho\n00000 \ud802\udd19\ud802\udd0d\ud802\udd10\ud802\udd13\ud802\udd04\ud802\udd00\ud802\udd11\ud802\udd0f\ud802\udd06\ud802\udd1a\ud802\udd11\ud802\udd0d\ud802\udd0d\ud802\udd0e\ud802\udd07\ud802\udd11\ud802\udd1a\ud802\udd1b\ud802\udd05\ud802\udd11\ud802\udd06\ud802\udd1b\ud802\udd0b\ud802\udd00\ud802\udd03\ud802\udd1b\ud802\udd13\ud802\udd0d\ud802\udd12\ud802\udd0d\ud802\udd06\ud802\udd10\ud802\udd15\ud802\udd13\ud802\udd04\ud802\udd1a\ud802\udd19\ud802\udd13\ud802\udd01\ud802\udd0f\ud802\udd11\ud802\udd09\ud802\udd03\ud802\udd09\ud802\udd06\ud802\udd19\ud802\udd0b\ud802\udd0e\ud802\udd10\ud802\udd07\ud802\udd10\ud802\udd01\ud802\udd07\ud802\udd03\ud802\udd0e\ud802\udd0c\ud802\udd0a\ud802\udd03\ud802\udd18\ud802\udd13\ud802\udd0d\ud802\udd1b\ud802\udd16\ud802\udd02\n00001 \ud802\udd10\ud802\udd12\ud802\udd02\ud802\udd08\ud802\udd02\ud802\udd19\ud802\udd1a\ud802\udd05\ud802\udd06\ud802\udd06\ud802\udd0b\ud802\udd01\ud802\udd09\ud802\udd01\ud802\udd19\ud802\udd12\ud802\udd04\ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd04\ud802\udd0a\ud802\udd09\ud802\udd09\ud802\udd1a\ud802\udd12\ud802\udd0a\ud802\udd12\ud802\udd09\ud802\udd0d\ud802\udd06\ud802\udd00\ud802\udd14\ud802\udd08\ud802\udd03\ud802\udd1a\ud802\udd05\ud802\udd05\ud802\udd02\ud802\udd15\ud802\udd18\ud802\udd08\ud802\udd01\ud802\udd18\ud802\udd00\ud802\udd09\ud802\udd11\ud802\udd04\ud802\udd11\ud802\udd06\ud802\udd00\ud802\udd05\ud802\udd10\ud802\udd16\ud802\udd05\ud802\udd13\ud802\udd08\ud802\udd04\ud802\udd1b\ud802\udd10\ud802\udd03\ud802\udd18\ud802\udd1a\ud802\udd16\n00002 \ud802\udd18\ud802\udd03\ud802\udd01\ud802\udd12\ud802\udd13\ud802\udd16\ud802\udd1b\ud802\udd13\ud802\udd1a\ud802\udd0c\ud802\udd00\ud802\udd18\ud802\udd0f\ud802\udd05\ud802\udd05\ud802\udd00\ud802\udd15\ud802\udd1a\ud802\udd06\ud802\udd01\ud802\udd0c\ud802\udd13\ud802\udd09\ud802\udd1a\ud802\udd01\ud802\udd03\ud802\udd01\ud802\udd05\ud802\udd05\ud802\udd00\ud802\udd17\ud802\udd08\ud802\udd17\ud802\udd09\ud802\udd01\ud802\udd08\ud802\udd13\ud802\udd12\ud802\udd18\ud802\udd15\ud802\udd05\ud802\udd0a\ud802\udd19\ud802\udd0f\ud802\udd02\ud802\udd07\ud802\udd09\ud802\udd09\ud802\udd06\ud802\udd12\ud802\udd09\ud802\udd06\ud802\udd0a\ud802\udd14\ud802\udd04\ud802\udd14\ud802\udd1a\ud802\udd19\ud802\udd03\ud802\udd16\ud802\udd04\ud802\udd06\ud802\udd03\ud802\udd17\n00003 \ud802\udd0f\ud802\udd1b\ud802\udd03\ud802\udd08\ud802\udd17\ud802\udd18\ud802\udd13\ud802\udd02\ud802\udd15\ud802\udd19\ud802\udd16\ud802\udd04\ud802\udd06\ud802\udd0c\ud802\udd1b\ud802\udd16\ud802\udd1b\ud802\udd0c\ud802\udd14\ud802\udd00\ud802\udd13\ud802\udd00\ud802\udd02\ud802\udd0f\ud802\udd0f\ud802\udd13\ud802\udd09\ud802\udd18\ud802\udd17\ud802\udd11\ud802\udd03\ud802\udd15\ud802\udd09\ud802\udd17\ud802\udd15\ud802\udd16\ud802\udd0d\ud802\udd0b\ud802\udd00\ud802\udd17\ud802\udd02\ud802\udd0c\ud802\udd06\ud802\udd17\ud802\udd13\ud802\udd04\ud802\udd1a\ud802\udd0e\ud802\udd11\ud802\udd01\ud802\udd05\ud802\udd0d\ud802\udd0d\ud802\udd12\ud802\udd1b\ud802\udd18\ud802\udd0b\ud802\udd0c\ud802\udd13\ud802\udd14\ud802\udd04\ud802\udd04\ud802\udd01\ud802\udd03\n00004 \ud802\udd17\ud802\udd00\ud802\udd13\ud802\udd08\ud802\udd0f\ud802\udd12\ud802\udd17\ud802\udd07\ud802\udd16\ud802\udd05\ud802\udd0f\ud802\udd1b\ud802\udd0c\ud802\udd0e\ud802\udd1a\ud802\udd04\ud802\udd10\ud802\udd04\ud802\udd04\ud802\udd1a\ud802\udd04\ud802\udd12\ud802\udd06\ud802\udd0b\ud802\udd11\ud802\udd0b\ud802\udd19\ud802\udd01\ud802\udd0f\ud802\udd0d\ud802\udd00\ud802\udd01\ud802\udd04\ud802\udd0a\ud802\udd0d\ud802\udd03\ud802\udd1a\ud802\udd07\ud802\udd19\ud802\udd0a\ud802\udd11\ud802\udd0a\ud802\udd06\ud802\udd08\ud802\udd14\ud802\udd0b\ud802\udd13\ud802\udd1a\ud802\udd17\ud802\udd10\ud802\udd0d\ud802\udd11\ud802\udd1a\ud802\udd0f\ud802\udd1b\ud802\udd07\ud802\udd0e\ud802\udd14\ud802\udd03\ud802\udd07\ud802\udd04\ud802\udd19\ud802\udd07\ud802\udd00\n00005 \ud802\udd13\ud802\udd14\ud802\udd05\ud802\udd0a\ud802\udd08\ud802\udd06\ud802\udd08\ud802\udd01\ud802\udd05\ud802\udd04\ud802\udd0c\ud802\udd00\ud802\udd10\ud802\udd0f\ud802\udd11\ud802\udd01\ud802\udd1b\ud802\udd1b\ud802\udd03\ud802\udd0f\ud802\udd0e\ud802\udd1a\ud802\udd15\ud802\udd00\ud802\udd0b\ud802\udd13\ud802\udd19\ud802\udd02\ud802\udd07\ud802\udd1b\ud802\udd04\ud802\udd10\ud802\udd03\ud802\udd11\ud802\udd08\ud802\udd0c\ud802\udd0e\ud802\udd10\ud802\udd08\ud802\udd07\ud802\udd03\ud802\udd12\ud802\udd06\ud802\udd13\ud802\udd0d\ud802\udd13\ud802\udd0b\ud802\udd08\ud802\udd02\ud802\udd17\ud802\udd08\ud802\udd09\ud802\udd15\ud802\udd17\ud802\udd13\ud802\udd0d\ud802\udd10\ud802\udd17\ud802\udd09\ud802\udd11\ud802\udd04\ud802\udd07\ud802\udd16\ud802\udd16\n00006 \ud802\udd0c\ud802\udd08\ud802\udd0a\ud802\udd0c\ud802\udd14\ud802\udd0f\ud802\udd0b\ud802\udd19\ud802\udd17\ud802\udd13\ud802\udd07\ud802\udd11\ud802\udd0d\ud802\udd06\ud802\udd04\ud802\udd0a\ud802\udd09\ud802\udd1b\ud802\udd16\ud802\udd08\ud802\udd0d\ud802\udd11\ud802\udd16\ud802\udd01\ud802\udd00\ud802\udd01\ud802\udd0d\ud802\udd07\ud802\udd09\ud802\udd08\ud802\udd02\ud802\udd0b\ud802\udd15\ud802\udd03\ud802\udd10\ud802\udd02\ud802\udd01\ud802\udd05\ud802\udd13\ud802\udd18\ud802\udd16\ud802\udd03\ud802\udd18\ud802\udd0b\ud802\udd0e\ud802\udd08\ud802\udd06\ud802\udd19\ud802\udd16\ud802\udd00\ud802\udd15\ud802\udd14\ud802\udd18\ud802\udd03\ud802\udd0a\ud802\udd0e\ud802\udd11\ud802\udd01\ud802\udd0e\ud802\udd18\ud802\udd07\ud802\udd14\ud802\udd12\ud802\udd05\n00007 \ud802\udd10\ud802\udd11\ud802\udd0b\ud802\udd0d\ud802\udd1a\ud802\udd05\ud802\udd0d\ud802\udd16\ud802\udd03\ud802\udd0b\ud802\udd0c\ud802\udd08\ud802\udd01\ud802\udd01\ud802\udd0f\ud802\udd16\ud802\udd11\ud802\udd00\ud802\udd0a\ud802\udd05\ud802\udd0c\ud802\udd11\ud802\udd00\ud802\udd0b\ud802\udd0f\ud802\udd06\ud802\udd15\ud802\udd10\ud802\udd01\ud802\udd04\ud802\udd05\ud802\udd10\ud802\udd10\ud802\udd1a\ud802\udd12\ud802\udd15\ud802\udd05\ud802\udd0c\ud802\udd1a\ud802\udd06\ud802\udd0d\ud802\udd12\ud802\udd1a\ud802\udd05\ud802\udd06\ud802\udd08\ud802\udd11\ud802\udd15\ud802\udd00\ud802\udd08\ud802\udd14\ud802\udd0a\ud802\udd17\ud802\udd03\ud802\udd16\ud802\udd14\ud802\udd0e\ud802\udd02\ud802\udd1a\ud802\udd08\ud802\udd19\ud802\udd10\ud802\udd0e\ud802\udd15\n00008 \ud802\udd19\ud802\udd13\ud802\udd1b\ud802\udd18\ud802\udd10\ud802\udd12\ud802\udd07\ud802\udd0c\ud802\udd0a\ud802\udd0e\ud802\udd01\ud802\udd0e\ud802\udd10\ud802\udd12\ud802\udd0a\ud802\udd04\ud802\udd03\ud802\udd13\ud802\udd04\ud802\udd17\ud802\udd00\ud802\udd14\ud802\udd02\ud802\udd16\ud802\udd17\ud802\udd16\ud802\udd1b\ud802\udd14\ud802\udd00\ud802\udd09\ud802\udd12\ud802\udd0e\ud802\udd19\ud802\udd0a\ud802\udd13\ud802\udd0c\ud802\udd06\ud802\udd0d\ud802\udd08\ud802\udd08\ud802\udd16\ud802\udd00\ud802\udd0c\ud802\udd06\ud802\udd13\ud802\udd03\ud802\udd05\ud802\udd11\ud802\udd04\ud802\udd18\ud802\udd16\ud802\udd0c\ud802\udd13\ud802\udd14\ud802\udd12\ud802\udd06\ud802\udd14\ud802\udd04\ud802\udd01\ud802\udd0d\ud802\udd12\ud802\udd07\ud802\udd0a\ud802\udd12\n00009 \ud802\udd15\ud802\udd15\ud802\udd0c\ud802\udd06\ud802\udd0c\ud802\udd10\ud802\udd02\ud802\udd0e\ud802\udd12\ud802\udd16\ud802\udd13\ud802\udd04\ud802\udd0e\ud802\udd0a\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd08\ud802\udd12\ud802\udd02\ud802\udd14\ud802\udd04\ud802\udd14\ud802\udd06\ud802\udd04\ud802\udd00\ud802\udd01\ud802\udd03\ud802\udd11\ud802\udd05\ud802\udd02\ud802\udd09\ud802\udd0a\ud802\udd14\ud802\udd13\ud802\udd14\ud802\udd17\ud802\udd09\ud802\udd19\ud802\udd16\ud802\udd14\ud802\udd19\ud802\udd00\ud802\udd13\ud802\udd0a\ud802\udd0c\ud802\udd11\ud802\udd10\ud802\udd10\ud802\udd13\ud802\udd09\ud802\udd01\ud802\udd09\ud802\udd19\ud802\udd1b\ud802\udd09\ud802\udd0c\ud802\udd1a\ud802\udd17\ud802\udd15\ud802\udd10\ud802\udd1a\ud802\udd0c\ud802\udd09\n$ <\/code><\/pre>\n\n\n\n<p>Ja edellisten koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--pho\", argv&#91;c])) { \/\/ phoenician alphabet, (fi \"foinikialaiset aakkoset\")\n\n\t\/\/phoenician: \ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd03\ud802\udd04\ud802\udd05\ud802\udd06\ud802\udd07\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd0b\ud802\udd0c\ud802\udd0d\ud802\udd0e\ud802\udd0f\ud802\udd10\ud802\udd11\ud802\udd12\ud802\udd13\ud802\udd14\ud802\udd15\ud802\udd16\ud802\udd17\ud802\udd18\ud802\udd19\ud802\udd1a\ud802\udd1b\ud802\udd1c\ud802\udd1d\ud802\udd1e\ud802\udd1f\ud802\udd20\ud802\udd21\ud802\udd22\ud802\udd23\ud802\udd24\ud802\udd25\ud802\udd26\ud802\udd27\ud802\udd28\ud802\udd29\ud802\udd2a\ud802\udd2b\ud802\udd2c\ud802\udd2d\ud802\udd2e\ud802\udd2f\n\tdigits = \"\ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd03\ud802\udd04\ud802\udd05\ud802\udd06\ud802\udd07\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd0b\ud802\udd0c\ud802\udd0d\ud802\udd0e\ud802\udd0f\ud802\udd10\ud802\udd11\ud802\udd12\ud802\udd13\ud802\udd14\ud802\udd15\ud802\udd16\ud802\udd17\ud802\udd18\ud802\udd19\ud802\udd1a\ud802\udd1b\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--som\", argv&#91;c]) ||<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty &#8211;depth kytkin, jolla voi m\u00e4\u00e4ritell\u00e4 copy reversen syvyyden. Lis\u00e4sin kytkimen, jotta voidaan kokeilla uuden copy-reverse funktion toimintaa. T\u00e4m\u00e4n testailun mahdollistamiseksi on lis\u00e4tty my\u00f6s debukki DEBUG2F<\/p>\n\n\n\n<p>Seuraavassa DEBUG2F:n tulostamaa listaa &#8211;depth0 kytkimell\u00e4: &#8211;depth0 vastaa tilannetta, jossa ei k\u00e4ytet\u00e4 copy-reverse\u00e4. T\u00e4ss\u00e4 debukissa kello kiert\u00e4\u00e4 koko ajan v\u00e4li\u00e4 0-255 koko ajan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>101728  70707070 70707071 71717171 71717171 71727272 72727272 72727373 73737373\n101760  73737374 74747474 74747474 75757575 75757575 75767676 76767676 76767677\n101792  77777777 77777778 78787878 78787878 78797979 79797979 79797a7a 7a7a7a7a\n101824  7a7a7b7b 7b7b7b7b 7b7b7b7b 7c7c7c7c 7c7c7c7c 7c7d7d7d 7d7d7d7d 7d7d7e7e\n101856  7e7e7e7e 7e7e7e7f 7f7f7f7f 7f7f7f7f 80808080 80808080 80818181 81818181\n101888  81818282 82828282 82828283 83838383 83838383 83848484 84848484 84848585\n101920  85858585 85858586 86868686 86868686 87878787 87878787 87878888 88888888\n101952  88888989 89898989 89898989 8a8a8a8a 8a8a8a8a 8a8b8b8b 8b8b8b8b 8b8b8b8c\n101984  8c8c8c8c 8c8c8c8d 8d8d8d8d 8d8d8d8d 8d8e8e8e 8e8e8e8e 8e8e8f8f 8f8f8f8f\n102016  8f8f8f90 90909090 90909090 91919191 91919191 91919292 92929292 92929293\n102048  93939393 93939393 94949494 94949494 94959595 95959595 95959696 96969696\n102080  96969697 97979797 97979797 97989898 98989898 98989999 99999999 99999999\n102112  9a9a9a9a 9a9a9a9a 9b9b9b9b 9b9b9b9b 9b9c9c9c 9c9c9c9c 9c9c9c9d 9d9d9d9d\n102144  9d9d9d9d 9e9e9e9e 9e9e9e9e 9e9f9f9f 9f9f9f9f 9f9fa0a0 a0a0a0a0 a0a0a0a0\n102176  a1a1a1a1 a1a1a1a1 a2a2a2a2 a2a2a2a2 a2a2a3a3 a3a3a3a3 a3a3a3a4 a4a4a4a4\n102208  a4a4a4a4 a5a5a5a5 a5a5a5a5 a5a6a6a6 a6a6a6a6 a6a6a7a7 a7a7a7a7 a7a7a7a7\n102240  a8a8a8a8 a8a8a8a8 a8a9a9a9 a9a9a9a9 a9a9aaaa aaaaaaaa aaaaaaaa abababab\n102272  abababab acacacac acacacac acacadad adadadad adadadae aeaeaeae aeaeaeae\n102304  aeafafaf afafafaf afb0b0b0 b0b0b0b0 b0b0b0b1 b1b1b1b1 b1b1b1b1 b2b2b2b2\n102336  b2b2b2b2 b2b3b3b3 b3b3b3b3 b3b3b3b4 b4b4b4b4 b4b4b4b4 b5b5b5b5 b5b5b5b5\n102368  b5b6b6b6 b6b6b6b6 b6b6b7b7 b7b7b7b7 b7b7b7b7 b8b8b8b8 b8b8b8b8 b8b9b9b9\n102400  c7c7c8c8 c8c8c8c8 c8c8c8c9 c9c9c9c9 c9c9c9c9 c9cacaca cacacaca cacacbcb\n102432  cbcbcbcb cbcbcbcc cccccccc cccccccc cdcdcdcd cdcdcdcd cdcdcece cececece\n102464  cececfcf cfcfcfcf cfcfcfcf d0d0d0d0 d0d0d0d0 d0d1d1d1 d1d1d1d1 d1d1d1d2\n102496  d2d2d2d2 d2d2d2d3 d3d3d3d3 d3d3d3d3 d3d4d4d4 d4d4d4d4 d4d4d5d5 d5d5d5d5\n102528  d5d5d5d6 d6d6d6d6 d6d6d6d6 d7d7d7d7 d7d7d7d7 d7d7d8d8 d8d8d8d8 d8d8d8d9\n102560  d9d9d9d9 d9d9d9d9 dadadada dadadada dadbdbdb dbdbdbdb dbdbdbdc dcdcdcdc\n102592  dcdcdcdd dddddddd dddddddd dddedede dededede dededfdf dfdfdfdf dfdfdfdf<\/code><\/pre>\n\n\n\n<p>&#8211;depth1 vastaa edellist\u00e4 versiota copy-reversest\u00e4, siin\u00e4 copy ja reverse lohkot seuraavat toisiaan, ensin kellojonon luvut kasvavat lohkon ja seuraavaksi ne v\u00e4henev\u00e4t lohkon:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>26144  4e4e4e4e 4e4e4e4e 4e4e4e4e 4e4e4e4e 4e4e4f4f 4f4f4f4f 4f4f4f4f 4f4f4f4f\n26176  4f4f4f4f 4f4f6968 68686868 68686868 68686868 68686868 68686868 68686868\n26208  68686868 68676767 67676767 67676767 67676767 67676767 67676767 67676f6f\n26240  6f6f6f6f 6f6f6f6f 6f6f6f6f 6f6f6f6f 6f6f6f6f 6f6f7070 70707070 70707070\n26272  70707070 70707070 70707070 70707070 70707071 71717171 71717171 71717171\n26304  71717171 71717171 71717171 71717171 71727272 72727272 72727272 72727272\n26336  72727272 72727272 72727272 72727273 73737373 73737373 73737373 73737373\n26368  73737373 73737373 73888888 88888888 88888888 88888888 88888888 88888888\n26400  88888888 88888887 87878787 87878787 87878787 87878787 87878787 87878787\n26432  87878787 86868686 86868686 86868686 86868686 86868686 86868686 86868686\n26464  86868585 85858585 85858585 85858585 85858585 85858585 85858585 85858585\n26496  84848484 84848484 84848484 84848484 84848484 84848484 84848484 84838383\n26528  83838383 83838383 83838383 83838383 83838383 83838383 83838382 82828282\n26560  82828282 82828282 82828282 82828282 82828282 8282a1a1 a1a1a1a1 a1a1a1a1\n26592  a1a1a1a1 a1a1a1a1 a1a1a1a1 a1a1a1a1 a1a2a2a2 a2a2a2a2 a2a2a2a2 a2a2a2a2\n26624  a2a2a2a2 a2a2a2a2 a2a2a2a2 a2a2a2a3 a3a3a3a3 a3a3a3a3 a3a3a3a3 a3a3a3a3\n26656  a3a3a3a3 a3a3a3a3 a3a3a3a3 a3a4a4a4 a4a4a4a4 a4a4a4a4 a4a4a4a4 a4a4a4a4\n26688  a4a4a4a4 a4a4a4a4 a4a4a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5\n26720  a5a5a5a5 a5a5a5a5 a6a6a6a6 a6a6a6a6 a6a6a6a6 a6a6a6a6 a6a6a6a6 a6d4d4d4\n26752  d3d3d3d3 d3d3d3d3 d3d3d3d3 d3d3d3d3 d3d3d3d3 d3d3d3d3 d3d3d3d3 d3d2d2d2\n26784  d2d2d2d2 d2d2d2d2 d2d2d2d2 d2d2d2d2 d2d2d2d2 d2d2d2d2 d2d2d2d1 d1d1d1d1\n26816  d1d1d1d1 d1d1d1d1 d1d1d1d1 d1d1d1d1 d1d1d1d1 d1d1d1d1 d1d0d0d0 d0d0d0d0\n26848  d0d0d0d0 d0d0d0d0 d0d0d0d0 d0d0d0d0 d0d0d0d0 d0d0cfe0 e0e0e0e0 e0e0e1e1\n26880  e1e1e1e1 e1e1e1e1 e1e1e1e1 e1e1e1e1 e1e1e1e1 e1e1e1e1 e1e1e1e1 e2e2e2e2\n26912  e2e2e2e2 e2e2e2e2 e2e2e2e2 e2e2e2e2 e2e2e2e2 e2e2e2e2 e2e3e3e3 e3e3e3e3\n26944  e3e3e3e3 e3e3e3e3 e3e3e3e3 e3e3e3e3 e3e3e3e3 e3e3e3e4 e4e4e4e4 e4e4e4e4\n26976  e4e4e4e4 e4e4e4e4 e4e4e4e4 e4e4e4e4 e4e4e4e4 e4e5e5e5 e5f7f7f7 f7f7f7f7\n27008  f7f7f7f7 f7f7f7f7 f7f7f7f7 f6f6f6f6 f6f6f6f6 f6f6f6f6 f6f6f6f6 f6f6f6f6\n27040  f6f6f6f6 f6f6f6f6 f6f6f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5\n27072  f5f5f5f5 f5f5f5f4 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f4f4f4\n27104  f4f4f4f4 f4f3f3f3 f3f3f3f3 f3f3f3f3 f3f3f3f3 f3f3f3f3 f3f3f3f3 f3f3f3f3\n27136  f3f3f3f2 f2f2f2f2 f2f2f2f2 f2f2f2f2 f2f2f207 07070707 07070707 07070707\n27168  07070707 07070708 08080808 08080808 08080808 08080808 08080808 08080808\n27200  08080808 08090909 09090909 09090909 09090909 09090909 09090909 09090909\n27232  0909090a 0a141414 14141515 15151515 15151515 15151616 16161616 16161616<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 copy-reverse debukkilista &#8211;depth4 kytkimell\u00e4: t\u00e4m\u00e4 versio on &#8220;voimassa&#8221; oletuksena, ja se monimutkaistaa eri copy-reverse lohkojen j\u00e4rjestyst\u00e4 entisest\u00e4\u00e4n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>12096  e1e1e1e1 e1e1e1e1 e0e0dfdf dfdfdfdf dfdfdfdf dfdfdfdf dfdfdfdf dfdfdfdf\n12128  dfdfdfdf dfdfdfdf dfdedede dededede dededede dededede dededede dededede\n12160  dededede dedede92 92929292 92919191 91919191 91919191 91919191 91919191\n12192  91919191 91919191 91919191 90909090 90909090 909090b7 b7b7b7b7 b7b7b7b7\n12224  b7b7b7b7 b7b7b7b7 b7b7b7b7 b7b7b7b7 b7b7b7b7 b7b6b6b6 b6e2e2e2 e2e3e3e3\n12256  e3e3e3e3 e3e3e3e3 e3e3e3e3 e3e3e3e3 e3e3fcfc fcfcfbfb fbfbfbfb fbfbfbfb\n12288  fbfbfbfb fbfbfbfb fbfbfbfb fbfbfbfb fbfbfbfb fbf6f6f6 f6f6f6f6 f6f6f6f6\n12320  f6f6f6f6 f6f6f6f6 f6f5f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5 f5f5f5f5\n12352  f5f5f5f5 f5f5f5f5 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f4f4f4 f4f41818\n12384  19191919 19191919 19191919 19191919 19191919 19191919 19191919 1919191a\n12416  1a1a1a1a 1a1a1a1a f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f9fa fafafafa fafafafa\n12448  fafafafa fafafafa 1c1c1c1c 1c1c1b1b 1b1b1b1b 1b1b1b1b 1b1b1b1b 1b1b1b1b\n12480  1b1b1b1b 1b1b1b1b 1b1b1b1b 1b1a1a1a 1a1a1a1a 1a1a1a1a 1a1a1a1a 1a1a1a1a\n12512  1a1a1af9 f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f9f8 f8f8f8f8 f8f8f8f8 f8f8f8f8\n12544  f8f8f8f8 f8f8f8f8 f8f8f8f8 f8f8f8f8 f8f8f7f7 f7f7f7f7 f7f7f7f7 f7f7f7f7\n12576  f7f7f7f7 f7f7f7f7 f7f7f7f7 f7f7f7f7 f7f6f6f6 f6f6f6f6 f6f6f6f6 fafafafa\n12608  fafafafa fafafafa fafa1c1c 1c1c1c1c 1c1c1c1c 1c1c1c1f 1f1f1f1f 1f1f1f1f\n12640  1f1f1f1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e 1e1e1e1e\n12672  1e1e1d1d 1d1d1d1d 1d1d1d1d 1d1d1d1d 1d1d1d1d 1d1d1d1d 1d1d1d1d 1d1d1d1d\n12704  1c1c1c1c 1c1c1c1c 1c1c1c1c 1f1f1f1f 1f1f1f4a 4a4a4a4a 4a4a4a4a 4a4a4a4a\n12736  4a4a4a4a 4a4a4a4a 49494949 49494949 49494949 49494949 49494949 49494949\n12768  49636363 63636363 63646464 64646464 64646464 64646464 64646464 64646464\n12800  64646464 64646464 65656565 65656565 65656565 65656565 656b6b49 49496363\n12832  63636363 63636363 63636363 63636363 63636363 63626262 62626262 62626262\n12864  62626262 62626262 62626262 62626262 62626262 48484848 48494949 6b6b6a6a\n12896  6a6a6a6a 6a6a6a6a 6a6a6a6a 6a6a6a6a 6a6a6a6a 6a6a6a6a 6a6a6a6a 6a696969\n12928  70707070 70707070 70707070 70707070 70707070 70707070 70707171 71717171\n12960  71717171 71717171 71717171 71717171 71717171 71717171 71727272 72727272\n12992  72727272 72727272 72727272 72727272 72727272 72727272 73737373 6f6f6f6f\n13024  6f6f6f6f 6f6f6f6f 6f6f6f6f 6f6f6f6e 6e6e6e67 67676767 67676767 67676767\n13056  6767676e 67676767 67676768 68686868 68686868 68686868 68686868 68686868\n13088  68686868 68686868 68686969 69696969 69696969 69696969 69696969 69696969\n13120  69696969 69697070 7070706f 6f6f6f6f 6f6f6f6f 6f6f6f73 73737373 73737373\n13152  73737373 73737373 73737373 73737373 73737474 74747474 74747474 74747474\n13184  7474b0b0 b0b0b0b0 b0b0b0b0 b0b0b0b0 b0b0b0b0 b0afafaf afafafaf afafafaf\n13216  afafafaf afafafaf afafafac acacacac acacacac acacacac acacacac acacacac\n13248  acacacac acacacac acacabab abababb4 b4b4b4b4 b4b4b4b4 b4b4b4b4 b4b4b4b4\n13280  b4b4b4b4 b5afafaf afafafaf afafadad adadadad adadadad adadadad adadadad\n13312  adadadad adadadad adadadad adaeaeae aededede dededede dededede dededede\n13344  dedededf dfdfdfdf dfdfdfdf b8b8b8b8 b8b8b8b8 b8b8b8b8 b8b8b8b8 b8b8b8b8\n13376  b8b8b8b8 b8b8b8b8 b8b8b8b7 b7b7b7b7 b7b7b7b7 b7b7b7b7 b7b7b7b7 b7b7b7b7\n13408  b7b7b7b7 b7b7b7b7 b7b7b6b6 b6b6b6b6 b6b6b6b6 b6b6b6b6 b6b6b6b6 b6b6b6b6\n13440  b6b6b6b6 b6b6b6b6 b6b5b5b5 b5b5b5b5 b5b5b5b5 b5b5b5b5 b5b5b5b5 b5b5b5b5\n13472  b5b5b5b5 b5b5f9f9 02020202 02020202 02020202 020202fa fafafafa fafafafa\n13504  f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f9f9 f9f9f902 02020202\n13536  02020202 02020202 01010101 01010101 01010101 01010101 010101dd dddddddd<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 uudestaan copy-reverse:n koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define MAX_DEPTH 4 \/\/ now 4\n\nint depth = 4; \/\/ now 4\n\nunsigned int copyreverse = 1;\nunsigned long cblocks = 0;\nunsigned char lens = 4;\n\nstatic unsigned char ressu_copyreverse(int pdepth) \/\/ 2024 JariK\n{\n  static int reverse&#91;MAX_DEPTH] = {0}; \/\/ 0 = copy, 1 = reverse, 28.10.2022 JariK\n  static unsigned int len&#91;MAX_DEPTH] = {0};\n  static unsigned int count&#91;MAX_DEPTH] = {0};\n  static unsigned int low&#91;MAX_DEPTH] = {0};\n  static unsigned int high&#91;MAX_DEPTH] = {0};\n  static unsigned char bytes&#91;MAX_DEPTH]&#91;257] = {0};\n  \n  if(pdepth == 0) {\n#ifdef DEBUG2D\n    int c = ressu_clock();\n    \/\/fprintf(stdout,\", ch2:%02x\",c);\n    return(c);\n#else\n    return(ressu_clock());\n#endif\n  }\n\n  pdepth--;\n\n  \/\/ dividing clock stream into blocks\n  \/\/ and reversing every other block\n\n  \/\/ copy next block to bytes\n  \n  if(count&#91;pdepth] == 0) { \/\/ previous block ended\n    reverse&#91;pdepth] = !reverse&#91;pdepth];\n    len&#91;pdepth] = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 2; \/\/ block size\n    \/\/len&#91;pdepth] = (ressuct&#91;ressu_nonrandom() % ressuct_bytes] &amp; 3 ) + 2; \/\/ block size\n    \/\/len&#91;pdepth] = --lens + 2; \/\/ block size\n    \/\/len&#91;pdepth] = lens++ + 2; \/\/ block size\n    count&#91;pdepth] = len&#91;pdepth];\n    low&#91;pdepth] = 0;\n    high&#91;pdepth] = len&#91;pdepth];\n    rndbits2 += 2;\n#ifdef DEBUG2A\n    fprintf(stdout,\"\\nblk:\");\n    fprintf(stdout,\" depth:%d\", pdepth);\n    fprintf(stdout,\", reverse:%d\", reverse&#91;pdepth]);\n    fprintf(stdout,\", len:%d\", len&#91;pdepth]);\n    fprintf(stdout,\", count:%d\", count&#91;pdepth]);\n    fprintf(stdout,\", low:%d\", low&#91;pdepth]);\n    fprintf(stdout,\", high:%d\", high&#91;pdepth]);\n    fflush(stdout);\n#endif\n    for(int c = 0; c &lt; len&#91;pdepth]; c++) {\n      bytes&#91;pdepth]&#91;c] = ressu_copyreverse(pdepth); \/\/ block bytes\n#ifdef DEBUG2A\n      fprintf(stdout,\", b%d:%02x\", pdepth, bytes&#91;pdepth]&#91;c]);\n      newressu_output = 1;\n#endif\n    }\n  }\n  if(reverse&#91;pdepth]) { \/\/ reverse\n    \n    \/\/ get reversed byte to return\n    ch = bytes&#91;pdepth]&#91;--high&#91;pdepth]]; \/\/ reverse\n#ifdef DEBUG2E\n    fprintf(stdout,\", rev%d:%02x\", pdepth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;pdepth];\n\n  } else { \/\/ copy\n    \n    \/\/ get copied byte to return\n    ch = bytes&#91;pdepth]&#91;low&#91;pdepth]++]; \/\/ copy\n#ifdef DEBUG2E\n    fprintf(stdout,\", copy%d:%02x\", pdepth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;pdepth];\n  }\n\n  return(ch);\n}\n....\nstatic unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  if(copyreverse) {\n    ch = ressu_copyreverse(depth);\n  } else {\n    ch = ressu_clock();\n  } \/\/ end of if(copyreverse)\n\n#ifdef DEBUG2F\n  static unsigned int cols = 0;\n  if(cols % 32 == 0) {\n    if(cols &gt; 0)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%05u \",cols);\n    newressu_output = 1;\n  }\n  if(cols % 4 == 0)\n    fprintf(stdout,\" \");\n  fprintf(stdout,\"%02x\",ch);\n  newressu_output = 1;\n  cols++;\n#endif\n  \n  \/\/ statistics for theoretical\n  \/\/ random bits calculation (rndbits?)\n  \n  static int prevbyte = -1, clockcount = 0;\n  \n  if(prevbyte == -1)\n    prevbyte = ch;\n  if(prevbyte != ch) {\n    periods&#91;clockcount]++;\n    clockbytes += clockcount;\n#ifdef DEBUG2B\n    fprintf(stdout,\" %d\", clockcount);\n    newressu_output = 1;\n#endif\n    if((ch &amp; 1) != (prevbyte &amp; 1))\n      rndbits20++;\n    if((ch &amp; 2) != (prevbyte &amp; 2))\n      rndbits21++;\n    if((ch &amp; 4) != (prevbyte &amp; 4))\n      rndbits22++;\n    clockcount = 0;\n    prevbyte = ch;\n  }\n  clockcount++;\n  \n  return(ch);\n}\n....\n      } else if(!strncmp(\"--depth\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  depth = atoi(argv&#91;c] + 7);\n\n\t} else if(c + 1 &lt; argc &amp;&amp; isdigit(*(argv&#91;c + 1]))) {\n\t  depth = atoi(argv&#91;c + 1]);\n\t  c++;\n\t  \n\t} else {\n\t  depth = MAX_DEPTH;\n\t}\n\n\tif(depth &lt; 0 || depth &gt; MAX_DEPTH) {\n\t  fprintf(stderr,\"%s: --depth must be between 0 and %d(MAX_DEPTH)\\n\",\n\t\t  procname, MAX_DEPTH);\n\t  exit(2);\n\t}\n\n\tfprintf(stderr,\"depth:%d\\n\", depth);\n\n      } else if(!strcmp(\"--copyreverse\", argv&#91;c])) {\n....<\/code><\/pre>\n\n\n\n<p>V\u00e4hennetty sha256 kutsuja merkkijonosalakirjoituksessa (stream_bytes). Muutoksessa vuo jaetaan kahden kilon blokkeihin ja ennen kutakin lohkoa tehd\u00e4\u00e4n rekey. Rekey tehd\u00e4\u00e4n lohkon alussa jotta ensimm\u00e4inen lohko saa yht\u00e4 paljon vastusta kun muut lohkot. Seuraavassa stream sifferin uusi koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG17 2\n\nstatic unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic int streamt_pos = 0;\nstatic unsigned long streamt_input_bytes = 0;\n\n#define STREAM_REKEY 2048 \/\/ rekey blocksize now 2048\n\nvoid stream_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 32 bytes, 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n\n      if(streamt_input_bytes % STREAM_REKEY == 0) {\n\tstream_internalbytes(stream_key); \/\/ change key, first block also\n#ifdef DEBUG17\n\tressu_dump(\"rekey\", sizeof(stream_key), stream_key, 32);\n#endif\n      }\n\n      stream_internalbytes(streamt); \/\/ read next random bytes\n#ifdef DEBUG17\n      ressu_dump(\"nextdata\", sizeof(streamt), streamt, 32);\n#endif\n      \n      streamt_input_bytes += sizeof(streamt);\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n}\n\n#define STREAM_KEY_ROUNDS 4096 \/\/ should be fast enough and slow enough, now 4096\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --&gt; zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n  streamt_input_bytes = 0;  \n\n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n    HashFinal(stream_key, &amp;hash);\n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#define DEBUG21 2\n\n#ifdef DEBUG21\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" randomness from key, key=\");\n  dumpbin(stderr, size, key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n\n\n#ifdef DEBUG17\n  ressu_dump(\"first key\", sizeof(stream_key), stream_key, 32);\n#endif\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}<\/code><\/pre>\n\n\n\n<p>Uutta merkkijonosalausta varten tehty rutiini, jolla tarkistetaan ett\u00e4 luettavien lohkojen pituus ei vaikuta lopputulokseen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG67B 2\n  \n#ifdef DEBUG67B\n\n  unsigned char buffer4096&#91;4096];\n  unsigned char buffer&#91;128];\n  \n  stream_open(0, stream_default_key);\n\n  \/\/ fprintf(stderr,\"read\\n\");\n  stream_bytes(sizeof(buffer4096), buffer4096);\n  \/\/buffer4096&#91;2048] = 1;\n\n  \/\/ fprintf(stderr,\"second read\\n\");\n  \n  for(int c = 1; c &lt; sizeof(buffer); c++) {\n    \/\/ fprintf(stdout,\"%d\", c);\n    stream_open(0, stream_default_key);\n    for(int d = 0; d &lt; sizeof(buffer4096) - c + 1; d += c) {\n      \/\/ fprintf(stdout,\" %d\", d);\n      stream_bytes(c, buffer);\n      if(memcmp(buffer, buffer4096 + d, c)) {\n\tfprintf(stderr,\"%s: compare mismatch (stream), c=%d, d=%d\\n\", procname, c, d);\n\t\/\/ exit(1);\n      }\n    }\n    \/\/ fprintf(stdout,\"\\n\");\n  }\n#endif<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 &#8220;satunnaisbittej\u00e4&#8221; uudella merkkijonosalauksella: merkkijonosalauksessahan kaikki bitit tulevat avaimesta (t\u00e4ss\u00e4 kalakala).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --stream --keykalakala\n.\/newressu: stream_open(): randomness from key, key=kalakala\n00000 27281084605608457081531501986851370709686414480022220321837698223\n00001 50196974062299679493951123671720255202173544069980771871217845154\n00002 64571878591611298944198258340489830514397902153472936318015880787\n00003 56276177130692043623140067735003168766912939634720003061691896058\n00004 80677916856701380052555720705786946738098613731123374165164173386\n00005 89296520910005237197934068893281765599968940774225399790076045701\n00006 26402581879816045793049104222100769367612505127401420491317057905\n00007 63351216001515315102971247614920992527751677347772302340904331459\n00008 15650952137890401069377401649545591391989000803062919929133206301\n00009 60781036908628849558997640245764012828476873917802103627431856645\n$ <\/code><\/pre>\n\n\n\n<p>pseudoressu_bytes() kirjoitettu uudelleen: uusi versio on yksinkertaisempi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG17 2\n\n#define PSEUDORESSU_LIMIT 1048576 \/\/ limit between rekeys\n#define TOPUP_BYTES 32*1024 \/\/ bytes between topups\n#define TOPUP_SIZE 32 \/\/ topup size in bytes (32 bytes, 256 bits)\n#define aTOPUP_TWICE 2 \/\/ off by default\n\nunsigned long topup_bytes = TOPUP_BYTES;\n\nstatic unsigned char pseudoressu_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void pseudoressu_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic void pseudoressu_addrandomness(int size, unsigned char *buffer)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashUpdate(&amp;hash, buffer, size);\n  HashFinal(pseudoressu_key, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic void pseudoressu_topup()\n{\n  unsigned char topup&#91;TOPUP_SIZE]; \/\/ 32 bytes, 256 bits\n\n  ressu_genbytes(sizeof(topup), topup);\n#ifdef DEBUG17\n  ressu_dump(\"topup\", sizeof(topup), topup, 32);\n#endif\n  pseudoressu_addrandomness(sizeof(topup), topup);\n\n  memset(&amp;topup, 0, sizeof(topup)); \/\/ forget topup\n}\n\nvoid pseudoressu_bytes(int size, unsigned char *buffer) \/\/ JariK 2022\n{\n  int c;\n  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;\n  static unsigned char pseudoressu&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\n  for(c = 0; c &lt; size; c++) {\n    if(pseudoressu_pos == 0) {\n      if(topup_counter == 0) {\n\tif(initneeded) {\n\t  ressu_genbytes(sizeof(pseudoressu_key), pseudoressu_key); \/\/ set first key\n#ifdef DEBUG17\n\t  ressu_dump(\"first key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n\t  initneeded = 0;\n\t}\n\t\n\tpseudoressu_topup(); \/\/ add randomness to key, first block also\n#ifdef TOPUP_TWICE\n\tpseudoressu_topup(); \/\/ add randomness to key, first block also\n#endif\n\ttopup_counter = topup_bytes;\n      } \/\/ end of if(topup_counter == 0\n      \n      pseudoressu_internalbytes(pseudoressu); \/\/ get random bits using the key\n#ifdef DEBUG17\n      ressu_dump(\"next data\", sizeof(pseudoressu), pseudoressu, 32);\n#endif\n      topup_counter -= sizeof(pseudoressu);\n    } \/\/ end of if(pseudoressu_pos == 0\n\n    buffer&#91;c] ^= pseudoressu&#91;pseudoressu_pos];\n    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n  \n  pseudoressu_internalbytes(pseudoressu_key); \/\/ replace key with new random one\n#ifdef DEBUG17\n  ressu_dump(\"new key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n  memset(&amp;pseudoressu, 0, sizeof(pseudoressu)); \/\/ forget digest\n}<\/code><\/pre>\n\n\n\n<p>Uusia satunnaisbittej\u00e4 &#8211;pseudoressu optiolla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --pseudoressu\n00000 29460505014151281601100924199132273227086010155684512547989660166\n00001 57077071360270670435764043258361690665938432228338916492477965966\n00002 64333658056043669655608602871499145012510397841232418857055822225\n00003 73225418334979966602842865903866903483243503381863455409251399319\n00004 32365615129689991577173116030353715599929603406116209054144409018\n00005 98068722086576006637823894366404024757476223970952999021125249102\n00006 67036786557203699407262801438380888389807614501087826731348149555\n00007 51547294472026634009919001534592381514246826906669507359681974821\n00008 74809240439184671396649792427139597987209465167884075069535333064\n00009 87364485649129568088079540833250192150487249805144967788394074965\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 loppukevennykseksi uusi ressun satunnaisuutta k\u00e4ytt\u00e4v\u00e4 ohjelma, joka etsii sudokuja (newressusudoku).<\/p>\n\n\n\n<p>Seuraavassa haetaan yksi sudoku:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku \n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     3     |           |\nB | 4         |     6     |     5     |\nC |         9 |         5 |           |\n  +-----------+-----------+-----------+\nD | 9   8     |           | 1   2     |\nE | 7       5 | 1   2   8 |           |\nF | 3         |     4     |           |\n  +-----------+-----------+-----------+\nG | 5         |         2 | 7   9     |\nH | 6         | 8         | 5       4 |\nI |           |         6 |         8 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:4 digits:27\n$ \n<\/code><\/pre>\n\n\n\n<p>Sudokuja on niin paljon erilaisia, ett\u00e4 kaikkien tulostettujen sudokujen pit\u00e4isi olla ainutlaatuisia. Ohjelman ei pit\u00e4isi tulostaa samaa sudokua kahta kertaa. T\u00e4t\u00e4 on omalta osaltaan takaamassa pseudoressu, jolta newressusudoku hakee satunnaisbittins\u00e4 (sudoku_make()).<\/p>\n\n\n\n<p>Sudokun ulkomuotoon voi vaikuttaa &#8211;board -kytkimell\u00e4. &#8211;board:iin voi lis\u00e4t\u00e4 numeron, jolla valitaan milt\u00e4 sudoku n\u00e4ytt\u00e4\u00e4. Ensimm\u00e4isen\u00e4 &#8211;board1, joka on oletusarvo: T\u00e4m\u00e4 on sopiva muoto sudokun tulostukseen paperille ja ratkaistavaksi kyn\u00e4ll\u00e4. Voit muotoilla sudokut tekstink\u00e4sittelyll\u00e4 esimerkiksi nelj\u00e4\u00e4n sarakkeeseen, joissa on kolme sudokua, tai muuhun muotoon. Eniten merkint\u00f6j\u00e4 paperille mahtuu kun tulostat n\u00e4m\u00e4 1 sudoku \/ a4 lomake. Seuraavassa erilaiset &#8211;board kytkimet ja niiden tulosteet: &#8211;board0 kytkimell\u00e4 voit j\u00e4tt\u00e4\u00e4 teht\u00e4v\u00e4ruudukon tulostamatta. Ilman &#8211;board:in j\u00e4lkeist\u00e4 numeroa kytkin vaihdetaan vastakkaiseksi (0=false, 1\/muu=true).<\/p>\n\n\n\n<p>Ratkaisun tulostusmuotoon voi vaikuttaa &#8211;solution -kytkimell\u00e4, joka toimii samalla tavoin kun &#8211;board kytkin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --board1\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1   5 | 8         |         2 |\nB |         7 | 1         |     3     |\nC | 9       4 |           |           |\n  +-----------+-----------+-----------+\nD |         3 |         2 |           |\nE |           | 9   6     | 1   4     |\nF | 8         |     1     |         9 |\n  +-----------+-----------+-----------+\nG |     6     |         5 | 8   2     |\nH |     7     |           |         5 |\nI |         1 | 6         | 9         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:4 digits:27\n$ <\/code><\/pre>\n\n\n\n<p>&#8211;board2 tulostaa seuraavanlaisen listan n\u00e4m\u00e4 pienemm\u00e4t peliruudukot ovat hyvi\u00e4 ratkaisun tulostukseen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --board2\n  ABC DEF GHI \n +---+---+---+\nA|2  |3  |9 8|\nB|  5|   |  2|\nC|   |7  |   |\n +---+---+---+\nD|   |9 4| 5 |\nE|6  |   | 8 |\nF|5  | 31| 64|\n +---+---+---+\nG|36 | 5 | 2 |\nH|45 |  7|8  |\nI|12 |   |   |\n +---+---+---+\n  s:0 steps:0 rounds:5 digits:27\n$ <\/code><\/pre>\n\n\n\n<p>Jatkossa loput &#8211;board tulosteet<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --board3\n  ABCDEFGHI \n +---------+\nA|   3 9  2|\nB|769  23  |\nC|    71  9|\nD|4  1   8 |\nE|  8 4    |\nF|1 7      |\nG| 25  8  1|\nH| 136     |\nI|   5  6  |\n +---------+\n  s:0 steps:0 rounds:4 digits:27\n$ \n\n$ .\/newressusudoku --board4\n  ABCDEFGHI\n +---------\nA| 7 3     \nB|   6  47 \nC|4    12  \nD|3   4   7\nE|8  59 1 6\nF|5      8 \nG|9   8   2\nH|12   7 4 \nI|       51\n  s:0 steps:0 rounds:3 digits:27\n\n$ .\/newressusudoku --board5\n ABCDEFGHI \nA  1 43   \nB3 6 5918 \nC95   7   \nD6  8  7  \nE  8    3 \nF4     8 2\nG23     9 \nH         \nI7   2 6 1\n  s:0 steps:0 rounds:6 digits:27\n\n$ .\/newressusudoku --board6\n1        \n    38   \n4   5 3  \n72  1    \n9 6  58  \n   76 4 2\n       39\n 7 3   81\n  3 2 64 \n  s:0 steps:0 rounds:5 digits:27\n\n$\n\n$ .\/newressusudoku --board10\nAA8 AB1456 AC4569 AD7 AE369 AF36 AG2 AH56 AI3456\nBA24569 BB4567 BC245679 BD249 BE2369 BF8 BG1 BH56 BI3456\nCA246 CB3 CC246 CD1 CE26 CF5 CG468 CH7 CI9\nDA26 DB9 DC2678 DD28 DE5 DF4 DG678 DH3 DI12678\nEA23456 EB4567 EC245678 ED289 EE1 EF2367 EG46789 EH2689 EI24678\nFA2346 FB467 FC1 FD289 FE236789 FF2367 FG5 FH2689 FI24678\nGA7 GB1456 GC4569 GD258 GE28 GF12 GG3 GH125689 GI12568\nHA159 HB2 HC3 HD6 HE78 HF17 HG789 HH4 HI1578\nIA156 IB8 IC56 ID3 IE4 IF9 IG67 IH1256 II12567\n  s:0 steps:0 rounds:5 digits:27\n\n$ .\/newressusudoku --board11\n392  8               29  5  1 85  27 5  1    9   62 814 1 7 3  76           8 7  \n  s:0 steps:0 rounds:4 digits:27\n\n$ .\/newressusudoku --board20\n'AC' = \"6\", 'AD' = \"8\", 'AE' = \"2\", 'AH' = \"5\", 'BB' = \"5\", 'BG' = \"8\", 'BH' = \"9\", 'CD' = \"1\", 'CG' = \"3\", 'CH' = \"7\", 'DC' = \"5\", 'DE' = \"6\", 'DI' = \"9\", 'EB' = \"8\", 'EC' = \"3\", 'EF' = \"1\", 'FA' = \"2\", 'FC' = \"4\", 'FI' = \"3\", 'GB' = \"6\", 'GD' = \"3\", 'GI' = \"7\", 'HA' = \"1\", 'HC' = \"2\", 'HG' = \"5\", 'IA' = \"9\", 'IH' = \"2\"\n  s:0 steps:0 rounds:3 digits:27\n\n$ .\/newressusudoku --board21\n'AA' = \"4589\", 'AB' = \"6\", 'AC' = \"28\", 'AD' = \"2489\", 'AE' = \"48\", 'AF' = \"1\", 'AG' = \"47\", 'AH' = \"2347\", 'AI' = \"2457\", 'BA' = \"7\", 'BB' = \"128\", 'BC' = \"3\", 'BD' = \"248\", 'BE' = \"5\", 'BF' = \"2468\", 'BG' = \"146\", 'BH' = \"9\", 'BI' = \"1246\", 'CA' = \"1459\", 'CB' = \"1259\", 'CC' = \"12\", 'CD' = \"3\", 'CE' = \"46\", 'CF' = \"7\", 'CG' = \"146\", 'CH' = \"8\", 'CI' = \"12456\", 'DA' = \"189\", 'DB' = \"1789\", 'DC' = \"4\", 'DD' = \"1578\", 'DE' = \"2\", 'DF' = \"58\", 'DG' = \"1789\", 'DH' = \"6\", 'DI' = \"3\", 'EA' = \"2\", 'EB' = \"1378\", 'EC' = \"18\", 'ED' = \"6\", 'EE' = \"9\", 'EF' = \"348\", 'EG' = \"5\", 'EH' = \"147\", 'EI' = \"1478\", 'FA' = \"6\", 'FB' = \"13789\", 'FC' = \"5\", 'FD' = \"1478\", 'FE' = \"1348\", 'FF' = \"348\", 'FG' = \"2\", 'FH' = \"147\", 'FI' = \"14789\", 'GA' = \"1358\", 'GB' = \"12358\", 'GC' = \"1268\", 'GD' = \"12458\", 'GE' = \"7\", 'GF' = \"9\", 'GG' = \"1468\", 'GH' = \"124\", 'GI' = \"12468\", 'HA' = \"1358\", 'HB' = \"12358\", 'HC' = \"9\", 'HD' = \"12458\", 'HE' = \"13468\", 'HF' = \"234568\", 'HG' = \"14678\", 'HH' = \"1247\", 'HI' = \"124678\", 'IA' = \"18\", 'IB' = \"4\", 'IC' = \"7\", 'ID' = \"128\", 'IE' = \"168\", 'IF' = \"268\", 'IG' = \"3\", 'IH' = \"5\", 'II' = \"12689\"\n  s:0 steps:0 rounds:5 digits:27\n$<\/code><\/pre>\n\n\n\n<p>&#8211;board20 ja &#8211;board21 ovat terttu muodossa, ett\u00e4 sit\u00e4kin tulee ajateltua.<\/p>\n\n\n\n<p>Jos haluat ratkaisun tulosteen k\u00e4yt\u00e4 &#8211;solution -kytkint\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --solution\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     3   9 |     5   2 |           |\nB |           |     8     |           |\nC | 2       4 |           |     6     |\n  +-----------+-----------+-----------+\nD |         5 | 1         |           |\nE | 1         |           |     3     |\nF |           | 5   4   7 | 8       2 |\n  +-----------+-----------+-----------+\nG |           |     7   9 |         3 |\nH | 7         | 4       3 | 5         |\nI |     8     | 2         |         7 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:5 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8   3   9 | 6   5   2 | 1   7   4 |\nB | 6   1   7 | 3   8   4 | 2   5   9 |\nC | 2   5   4 | 7   9   1 | 3   6   8 |\n  +-----------+-----------+-----------+\nD | 4   2   5 | 1   3   8 | 7   9   6 |\nE | 1   7   8 | 9   2   6 | 4   3   5 |\nF | 9   6   3 | 5   4   7 | 8   1   2 |\n  +-----------+-----------+-----------+\nG | 5   4   1 | 8   7   9 | 6   2   3 |\nH | 7   9   2 | 4   6   3 | 5   8   1 |\nI | 3   8   6 | 2   1   5 | 9   4   7 |\n  +-----------+-----------+-----------+\n  s:0\n$ <\/code><\/pre>\n\n\n\n<p>Seuraavassa nelj\u00e4 aloittelijalle sopivaa sudokua:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --easy45 --sudokues4\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4         |     8   3 |     2   7 |\nB | 9       2 |         4 |         1 |\nC | 8   3   5 | 7   2   1 | 4   6   9 |\n  +-----------+-----------+-----------+\nD |     4   7 | 5   9     |     1     |\nE |         8 |         6 |     5     |\nF | 1       6 |         7 |           |\n  +-----------+-----------+-----------+\nG |     8     |           | 1   9   5 |\nH | 6         | 8       5 | 3   7     |\nI | 5       3 |     7   9 | 6   8   2 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:2 digits:45\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     5   7 | 3       9 |         4 |\nB | 6         |         1 | 9   2   5 |\nC |           |     5     |     3     |\n  +-----------+-----------+-----------+\nD |         8 | 6         | 5   1   2 |\nE |     7     | 9         |     8     |\nF | 4   2   1 |           | 7       6 |\n  +-----------+-----------+-----------+\nG |           | 1   4   5 |     7   9 |\nH |     6     | 8   9   3 | 2   5   1 |\nI | 9       5 | 2   6   7 | 3   4   8 |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:3 digits:45\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 2         |         7 |         4 |\nB | 3   1   7 | 2   5   4 |     8   9 |\nC | 5       6 |     9     | 3   7     |\n  +-----------+-----------+-----------+\nD | 7       3 | 1       6 | 9         |\nE | 1       9 |     8   3 | 7   4   6 |\nF |           |         2 | 8       1 |\n  +-----------+-----------+-----------+\nG | 9         |           |     6   3 |\nH |         2 | 3       5 |         7 |\nI | 4   3   5 |     6   9 |     1   8 |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:2 digits:45\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 8   7     |     6   2 |\nB | 5   7     |     1   6 | 8         |\nC | 2   8   6 | 4   9     | 3         |\n  +-----------+-----------+-----------+\nD |           |     3     |         6 |\nE | 9       7 |           | 1       8 |\nF |     2   1 |     5     | 9   3   4 |\n  +-----------+-----------+-----------+\nG | 3   6   5 |     8   4 | 7   2   1 |\nH | 7   9   4 | 5       1 | 6         |\nI | 8       2 |     6     |     9     |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:2 digits:45\n$ <\/code><\/pre>\n\n\n\n<p>Hiukan vaikeampia 33:n vihjeen sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --digits33 --sudokues4\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         3 | 1       9 | 4         |\nB | 2       6 |         5 |           |\nC |           | 7         | 8   6     |\n  +-----------+-----------+-----------+\nD |     1     | 5         |     2     |\nE | 3         |           |           |\nF |         8 | 4         | 6   5     |\n  +-----------+-----------+-----------+\nG | 8         |     5   7 |         9 |\nH | 7   9   2 | 3       4 | 5   8     |\nI | 4       5 |         8 |     1     |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:3 digits:33\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 6         | 3         | 9   1   2 |\nB |           |     1   9 |     6     |\nC | 1         |         6 | 8       7 |\n  +-----------+-----------+-----------+\nD |         4 | 6   9   5 |           |\nE | 9   8   2 | 1       3 |           |\nF |           |     8     |           |\n  +-----------+-----------+-----------+\nG |     7     |         2 |         1 |\nH |         3 |     6   1 |     8   5 |\nI |         6 | 7   5     |           |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:4 digits:33\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 9   5   2 | 7   8     |           |\nB |           |     2     |           |\nC |           | 4       3 |     5     |\n  +-----------+-----------+-----------+\nD |     6   7 | 9         | 8         |\nE | 1       9 | 3         | 4       6 |\nF |     3   4 | 6         |           |\n  +-----------+-----------+-----------+\nG |         5 | 8         |         3 |\nH |     9     |     3   7 | 5       1 |\nI | 8       3 |           |     9   2 |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:3 digits:33\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 5         |           | 4   1     |\nB | 1       3 | 4   2     |     9   8 |\nC |         8 |     6   9 |     5     |\n  +-----------+-----------+-----------+\nD |     8     |         2 |           |\nE | 4         | 5   9   3 | 2   8     |\nF | 3         |           | 6         |\n  +-----------+-----------+-----------+\nG |           |           |     7     |\nH |         1 | 9         | 5       4 |\nI | 2         | 8   3   4 | 9         |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:3 digits:33\n$ \n<\/code><\/pre>\n\n\n\n<p>27 vihjeisi\u00e4 helppoja sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           |     5   9 |\nB | 7         |           | 3         |\nC | 4         | 9   8     |         2 |\n  +-----------+-----------+-----------+\nD |           |     1   2 | 7   3   5 |\nE | 3         |           | 2   4     |\nF | 6         | 4   3     |           |\n  +-----------+-----------+-----------+\nG |           |           |     1     |\nH | 5       8 | 7         |           |\nI |     4     |         5 |     2   3 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:4 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         3 |     9     | 6   4     |\nB | 2   6     | 3   7     |     1     |\nC | 7       5 |           |           |\n  +-----------+-----------+-----------+\nD | 6         |         3 |     8   9 |\nE |           |           |           |\nF |     7     |     8     | 2   5     |\n  +-----------+-----------+-----------+\nG |           |         4 |     2     |\nH |           | 8   5     |         4 |\nI | 8         |     1   7 |           |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:6 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |         6 | 2         |\nB |     5   4 |     1     | 6         |\nC |     1     | 2         |         5 |\n  +-----------+-----------+-----------+\nD |           | 3   7   5 |           |\nE |           |           |           |\nF | 7   4     | 9       2 |           |\n  +-----------+-----------+-----------+\nG |         6 |           | 5   4   3 |\nH |           |         7 | 8   9     |\nI |     3     | 6       8 |           |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:4 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1     |           |           |\nB |     7     | 1         |         5 |\nC |         4 |     8   6 |     1   3 |\n  +-----------+-----------+-----------+\nD | 6         | 9         |         2 |\nE | 9       8 |           |           |\nF | 4   5     |     3     | 8         |\n  +-----------+-----------+-----------+\nG |           | 8       2 |     3     |\nH | 3   4     | 5         | 9       8 |\nI |           |           | 7         |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:5 digits:27\n$<\/code><\/pre>\n\n\n\n<p>Ja t\u00e4ss\u00e4 23 vihjeisi\u00e4 helppoja sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  $ .\/newressusudoku --digits23 --sudokues4\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1     | 6   8     |           |\nB |           |     4     | 9   3   5 |\nC | 9         | 2         |           |\n  +-----------+-----------+-----------+\nD | 1         |           | 3         |\nE | 6         | 9         | 5       2 |\nF |           |         7 |           |\n  +-----------+-----------+-----------+\nG |           |           |     6     |\nH |         4 |           | 7   5     |\nI | 2         |           | 8       9 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:7 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |           |     7     |\nB |           |         2 |     8     |\nC |     3     |     4   9 |           |\n  +-----------+-----------+-----------+\nD |     4     |     9   3 |           |\nE | 6         |           |     1   4 |\nF |     8     |         5 |           |\n  +-----------+-----------+-----------+\nG |           |     6   4 | 9   5     |\nH |     9     |         7 |           |\nI |         3 |           |         6 |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:4 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     8     |         2 |           |\nB | 1         |         6 |         2 |\nC | 5         |           |         1 |\n  +-----------+-----------+-----------+\nD |     3     |         1 |           |\nE |         4 |     2     |     7     |\nF |         9 | 3       8 |           |\n  +-----------+-----------+-----------+\nG |         2 |     8     |         4 |\nH | 8       5 |     7     | 9         |\nI |           |           |         5 |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:6 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 1         |           |           |\nB |     9     | 7   6     |     3     |\nC |           |         3 |         6 |\n  +-----------+-----------+-----------+\nD | 4       1 |     2   8 |           |\nE |     6     |           | 9         |\nF |         2 |           |         5 |\n  +-----------+-----------+-----------+\nG |           |         1 |         8 |\nH |           | 5         | 7   1   2 |\nI |         5 |     3     |           |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:6 digits:23\n$<\/code><\/pre>\n\n\n\n<p>Jos haluat n\u00e4it\u00e4 kauttaviiva (slashes) sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --slashes --digits27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         5 |         1 |         8 |\nB |     9     |     4     |     3     |\nC | 1         | 7         | 5         |\n  +-----------+-----------+-----------+\nD |         1 |         8 |         4 |\nE |     6     |     2     |     7     |\nF | 7         | 3         | 6         |\n  +-----------+-----------+-----------+\nG |         3 |         7 |         5 |\nH |     8     |     5     |     9     |\nI | 9         | 8         | 3         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:5 digits:27\n$ <\/code><\/pre>\n\n\n\n<p>Kauttaviivasudokut voidaan sekoittaa (mix()) siten ett\u00e4 kuitenkin rivit sarakkeet ja blokit s\u00e4ilyv\u00e4t samanlaisina:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --slashes --mix --digits27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     6     |         1 |         5 |\nB | 5         | 6         |     2     |\nC |         7 |     5     | 1         |\n  +-----------+-----------+-----------+\nD |     7     |         5 |         9 |\nE |         5 |     4     | 8         |\nF | 2         | 8         |     1     |\n  +-----------+-----------+-----------+\nG |         8 |     7     | 4         |\nH |     9     |         6 |         2 |\nI | 3         | 4         |     7     |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:4 digits:27\n$ \n<\/code><\/pre>\n\n\n\n<p>Seuraavassa kauttaviivasudoku ja sen sekoitettu versio, joista huomataan ett\u00e4 rivit, sarakkeet ja laatikot pysyv\u00e4t samoina:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --slashes --mix --verbose --digits27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 |         6 |         4 |\nB |     8     |     2     |     3     |\nC | 7         | 8         | 5         |\n  +-----------+-----------+-----------+\nD |         1 |         5 |         8 |\nE |     4     |     8     |     7     |\nF | 6         | 3         | 2         |\n  +-----------+-----------+-----------+\nG |         9 |         4 |         3 |\nH |     3     |     7     |     2     |\nI | 8         | 5         | 4         |\n  +-----------+-----------+-----------+\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 | 4         | 6         |\nB |     8     |         3 |     2     |\nC | 7         |     5     |         8 |\n  +-----------+-----------+-----------+\nD | 8         |     4     |         5 |\nE |         9 | 3         | 4         |\nF |     3     |         2 |     7     |\n  +-----------+-----------+-----------+\nG | 6         |     2     |         3 |\nH |     4     |         7 |     8     |\nI |         1 | 8         | 5         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:5 digits:27\n$<\/code><\/pre>\n\n\n\n<p>27 vihjeisi\u00e4 slashes sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --digits27 --slashes --mix --sudokues4\nA   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         9 |         8 |         1 |\nB |     2     |     3     |     6     |\nC | 5         | 2         | 4         |\n  +-----------+-----------+-----------+\nD |         4 |         9 |         7 |\nE |     1     |     2     |     4     |\nF | 9         | 7         | 6         |\n  +-----------+-----------+-----------+\nG |         8 |         6 |         2 |\nH |     4     |     9     |     7     |\nI | 7         | 3         | 5         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:5 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         3 |     8     | 6         |\nB |     7     |         6 |         9 |\nC | 8         | 7         |     1     |\n  +-----------+-----------+-----------+\nD |         8 |     3     | 5         |\nE | 2         | 5         |     9     |\nF |     1     |         9 |         8 |\n  +-----------+-----------+-----------+\nG | 1         | 3         |     8     |\nH |         2 |     1     | 7         |\nI |     8     |         4 |         6 |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:5 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         6 |         9 |         1 |\nB |     2     | 6         | 9         |\nC | 3         |     8     |     2     |\n  +-----------+-----------+-----------+\nD |     4     | 3         | 7         |\nE |         5 |         7 |         3 |\nF | 9         |     5     |     6     |\n  +-----------+-----------+-----------+\nG |     5     | 8         | 2         |\nH |         7 |         2 |         4 |\nI | 8         |     9     |     3     |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:5 digits:27\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8         |     3     | 7         |\nB |         5 |         9 |         4 |\nC |     2     | 1         |     9     |\n  +-----------+-----------+-----------+\nD |         7 |         2 |         5 |\nE | 1         |     9     | 4         |\nF |     5     | 4         |     7     |\n  +-----------+-----------+-----------+\nG | 7         |     5     | 9         |\nH |         8 |         6 |         1 |\nI |     3     | 9         |     4     |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:8 digits:27\n$<\/code><\/pre>\n\n\n\n<p>26 vihjeisi\u00e4 helppoja slashes sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --digits26 --slashes --mix --sudokues4\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 | 8         | 3         |\nB |     7     |     2     |     1     |\nC | 3         |         9 |         5 |\n  +-----------+-----------+-----------+\nD | 9         |         1 |         2 |\nE |     5     |     3     |     8     |\nF |         4 | 5         | 1         |\n  +-----------+-----------+-----------+\nG | 5         |           |         8 |\nH |     1     |     7     |     9     |\nI |         7 | 6         | 5         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:4 digits:26\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     |     7     |         2 |\nB | 5         | 4         | 8         |\nC |         7 |         8 |     6     |\n  +-----------+-----------+-----------+\nD |     9     |     2     |         3 |\nE | 1         | 8         | 7         |\nF |         3 |         4 |     9     |\n  +-----------+-----------+-----------+\nG |     1     |     6     |         7 |\nH |         2 |         3 |     1     |\nI | 3         | 1         |           |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:6 digits:26\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         | 4         |     1     |\nB |         3 |     7     | 5         |\nC |     5     |         9 |         8 |\n  +-----------+-----------+-----------+\nD | 6         | 3         |     2     |\nE |     9     |         1 |         6 |\nF |         5 |     8     | 3         |\n  +-----------+-----------+-----------+\nG |     7     |         8 |         2 |\nH | 9         |           |     4     |\nI |         4 |     2     | 9         |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:4 digits:26\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 2         |     8     | 1         |\nB |         4 | 9         |         2 |\nC |     1     |         7 |     9     |\n  +-----------+-----------+-----------+\nD |     5     |         4 |     8     |\nE | 8         |     6     | 4         |\nF |         3 | 2         |         6 |\n  +-----------+-----------+-----------+\nG | 6         |     4     | 5         |\nH |         5 |           |         7 |\nI |     2     |         1 |     6     |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:5 digits:26\n$<\/code><\/pre>\n\n\n\n<p>23 vihjeisi\u00e4 helppoja slashes sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --digits23 --slashes --mix --sudokues4\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 2         |           | 1         |\nB |         9 | 8         |     3     |\nC |     6     |         4 |         5 |\n  +-----------+-----------+-----------+\nD |     4     |         3 |         6 |\nE | 9         |     2     |           |\nF |         8 | 6         |     2     |\n  +-----------+-----------+-----------+\nG |           |     4     | 8         |\nH |     5     |           |         2 |\nI |         7 | 3         |     5     |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:6 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |         5 |         6 |\nB |     1     |           |     3     |\nC | 4         | 2         | 9         |\n  +-----------+-----------+-----------+\nD |         7 |         6 |         8 |\nE |     3     |     1     |     4     |\nF |           | 3         | 7         |\n  +-----------+-----------+-----------+\nG |         3 |           |         9 |\nH |     9     |     4     |     5     |\nI | 1         | 7         |           |\n  +-----------+-----------+-----------+\n  s:1 steps:0 rounds:5 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         1 | 9         |         2 |\nB |     7     |     5     | 6         |\nC | 9         |         6 |     5     |\n  +-----------+-----------+-----------+\nD |           |         5 |     3     |\nE |     8     |     1     |           |\nF |           |           |         5 |\n  +-----------+-----------+-----------+\nG |     5     |     4     | 8         |\nH |         9 | 2         |         6 |\nI | 4         |         7 |     9     |\n  +-----------+-----------+-----------+\n  s:2 steps:0 rounds:7 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         |     3     | 4         |\nB |         4 |         2 |         1 |\nC |     1     | 6         |     2     |\n  +-----------+-----------+-----------+\nD |           |         4 |         7 |\nE | 4         |           |           |\nF |     2     | 5         |     6     |\n  +-----------+-----------+-----------+\nG | 6         |     5     | 8         |\nH |         9 |         7 |         3 |\nI |     5     |           |     9     |\n  +-----------+-----------+-----------+\n  s:3 steps:0 rounds:5 digits:23\n$<\/code><\/pre>\n\n\n\n<p>Edell\u00e4 haetut olivat ns helppoja sudokuja, jotka ratkeavat varmasti p\u00e4\u00e4ttelem\u00e4ll\u00e4 ruutu ruudulta, teknisesti ne ratkeavat aina simplesolve() menetelm\u00e4ll\u00e4. Seuraavassa hakuun k\u00e4ytet\u00e4\u00e4n solve() menettely\u00e4: Alarivin muuttujat kertovat taustatietoa sudokusta. S: kentt\u00e4 kertoo sudokun numeron t\u00e4ss\u00e4 haussa, rounds: kertoo kuinka monta simple() menetelm\u00e4n kierrosta tarvitaan sudokun ratkaisussa. steps: kertoo kuinka monta solve():n askelta tarvitaan sudokun raatkaisussa koneellisesti. Edellisesi\u00e4 voi k\u00e4ytt\u00e4\u00e4 sudokun vaikeuden arvioinnissa. Seuraava sudoku on helppo, koska sek\u00e4 steps ja rounds ovat nollia. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressusudoku --solve\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 1   6     |     7   5 |\nB |           |         8 |           |\nC | 8       9 |     7     | 1   3     |\n  +-----------+-----------+-----------+\nD |           |           |           |\nE | 7         |     5     | 2       6 |\nF |         8 | 7         |     4     |\n  +-----------+-----------+-----------+\nG |         1 | 8   2     | 7         |\nH |         2 |         7 |           |\nI | 3         |         5 |     9   2 |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:0 digits:27\n$<\/code><\/pre>\n\n\n\n<p>Oletan ett\u00e4 ohjelman steps arvolla voidaan arvioida sudokun vaikeutta, ja olenkin etsinyt malliksi mielest\u00e4ni todella vaikeita sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |           |           |         3 |\nB | 1         | 8         | 6   7     |\nC |           |     5     |           |\n  +-----------+-----------+-----------+\nD | 3   9     |         8 | 1   2     |\nE |           |         5 |         4 |\nF |           | 6         |           |\n  +-----------+-----------+-----------+\nG |     4     |     3   2 | 7   1     |\nH | 2         | 1         |         8 |\nI | 9   1     | 5   8     |           |\n  +-----------+-----------+-----------+\n  s:0 steps:638 rounds:0 digits:26\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA | 1   2     |     9     |         4 |\nB | 4         |         8 |     7     |\nC | 8   3     | 2         |           |\n  +-----------+-----------+-----------+\nD | 6         |     2     |           |\nE | 2         | 1   6     | 4   3   5 |\nF |           |           | 7         |\n  +-----------+-----------+-----------+\nG |           |     8     | 2   4     |\nH |           |           | 5       3 |\nI |           |     4     |           |\n  +-----------+-----------+-----------+\n  s:0 steps:512 rounds:0 digits:25\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |     2     |         3 | 5         |\nB |     1     |     9     |           |\nC |     3   9 | 6         |           |\n  +-----------+-----------+-----------+\nD |         7 |           | 3         |\nE |         8 |     7     |         2 |\nF |           |         1 |     7   6 |\n  +-----------+-----------+-----------+\nG |         3 |         6 | 2         |\nH | 6   9     |     3   5 |     8     |\nI |           |           |           |\n  +-----------+-----------+-----------+\n  s:0 steps:489 rounds:0 digits:24\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |           |     5   8 |     2   9 |\nB |     8     |     2   1 |         6 |\nC |     2     |     7   3 |           |\n  +-----------+-----------+-----------+\nD |           |           |           |\nE |           |         4 | 5         |\nF |     6     | 2       9 |           |\n  +-----------+-----------+-----------+\nG | 2   1     | 3   9   7 |         8 |\nH |     7   4 |           | 9         |\nI | 3         |           |     7     |\n  +-----------+-----------+-----------+\n  s:0 steps:309 rounds:0 digits:27\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA | 5         | 9       2 |         6 |\nB |           |     7     | 5         |\nC | 6         |     5     |           |\n  +-----------+-----------+-----------+\nD | 7       1 |     9   3 |     6     |\nE | 4   2     | 6       7 | 3       8 |\nF |         6 | 5         |         7 |\n  +-----------+-----------+-----------+\nG | 1       8 |         9 |         2 |\nH |     7     |         5 |           |\nI |           |           | 9   7     |\n  +-----------+-----------+-----------+\n  s:0 steps:178 rounds:0 digits:30<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 mielest\u00e4ni vaikeita slashes sudokuja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     |         6 |         5 |\nB | 9         |     2     |           |\nC |           | 5         |     4     |\n  +-----------+-----------+-----------+\nD |         9 | 8         |     1     |\nE |     3     |         9 |         4 |\nF |           |     6     | 9         |\n  +-----------+-----------+-----------+\nG |     1     |         5 |         8 |\nH |         8 | 1         |     2     |\nI |           |     4     | 3         |\n  +-----------+-----------+-----------+\n  s:0 steps:413 rounds:0 digits:23\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 8         |           |\nB |           |         1 |         7 |\nC |     9     |     7     | 6         |\n  +-----------+-----------+-----------+\nD | 8         | 1         |     3     |\nE |         1 |         4 |         2 |\nF |     6     |     2     | 1         |\n  +-----------+-----------+-----------+\nG |         3 |         7 |         8 |\nH | 6         | 2         |     9     |\nI |     2     |     4     | 5         |\n  +-----------+-----------+-----------+\n  s:0 steps:553 rounds:0 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     3     |         5 |\nB | 4         |         1 |     2     |\nC |         2 | 9         | 4         |\n  +-----------+-----------+-----------+\nD |         5 | 1         | 3         |\nE | 8         |         3 |     7     |\nF |           |     9     |         1 |\n  +-----------+-----------+-----------+\nG |         4 | 5         | 2         |\nH |     3     |     4     |         6 |\nI | 6         |         8 |     4     |\n  +-----------+-----------+-----------+\n  s:0 steps:371 rounds:0 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 | 1         |     9     |\nB |     1     |     9     |         3 |\nC | 9         |         4 | 1         |\n  +-----------+-----------+-----------+\nD | 8         |         5 | 6         |\nE |     7     |     1     |           |\nF |         9 | 8         |     2     |\n  +-----------+-----------+-----------+\nG |         6 | 2         |     1     |\nH | 4         |         1 | 3         |\nI |     9     |     5     |         8 |\n  +-----------+-----------+-----------+\n  s:0 steps:197 rounds:0 digits:26<\/code><\/pre>\n\n\n\n<p>Oikeasti vaikeita sudokuja (muutettu steps: koodia), n\u00e4iss\u00e4 on 24 vihjett\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 | 5         | 9   1   4 |\nB |           |           |     3     |\nC | 2   3     |     1     |           |\n  +-----------+-----------+-----------+\nD | 7         |           | 3   9     |\nE |           |         4 |         1 |\nF |     5     | 6         |           |\n  +-----------+-----------+-----------+\nG | 9         | 3   8     | 5         |\nH |           |           | 7         |\nI | 3         | 7       2 |           |\n  +-----------+-----------+-----------+\n  s:0 steps:1 rounds:4 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         7 |         3 |\nB |         8 |     2   3 | 9       1 |\nC |           |     5     | 6   2     |\n  +-----------+-----------+-----------+\nD | 4         | 1         | 8       7 |\nE |           |           |     9   2 |\nF |           |           | 1   5     |\n  +-----------+-----------+-----------+\nG |         9 |           |     3     |\nH |     1     | 7         |           |\nI | 6         | 9         |           |\n  +-----------+-----------+-----------+\n  s:1 steps:2 rounds:6 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         |           |     6   3 |\nB |           | 7         | 4         |\nC |         9 |         4 |     2     |\n  +-----------+-----------+-----------+\nD |           | 8         |           |\nE |     3   1 |         6 |     5     |\nF | 5         |           |         8 |\n  +-----------+-----------+-----------+\nG |         4 | 1       3 |         6 |\nH | 6       8 |           |           |\nI |         3 | 5         | 7         |\n  +-----------+-----------+-----------+\n  s:2 steps:3 rounds:3 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 6         |     1   7 |           |\nB | 7         |         4 | 9   5     |\nC |           |           |           |\n  +-----------+-----------+-----------+\nD |           | 8       6 | 3         |\nE |     7     |         2 |           |\nF |     4     | 5         |         1 |\n  +-----------+-----------+-----------+\nG | 8       1 |     6     |     7     |\nH |           |     9     |     6     |\nI |         4 |         8 |         2 |\n  +-----------+-----------+-----------+\n  s:3 steps:4 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     8     | 7         |         9 |\nB |           |           | 8         |\nC | 4         |         1 |     3     |\n  +-----------+-----------+-----------+\nD |         8 |         6 |     4     |\nE |     9     | 5   4     |           |\nF | 3         | 2         |           |\n  +-----------+-----------+-----------+\nG |     2     | 3         |     6     |\nH |           | 1       2 | 3         |\nI | 1   4     |     6     |           |\n  +-----------+-----------+-----------+\n  s:4 steps:5 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         5 |     9   7 |\nB | 2   4     |         9 | 8         |\nC |           |           |           |\n  +-----------+-----------+-----------+\nD |     6     |     3   1 |           |\nE |     5     | 2         |     6   9 |\nF | 4         |           |     7     |\n  +-----------+-----------+-----------+\nG |         2 | 1         |     3     |\nH | 9         | 5         |         6 |\nI | 3         |           |     5     |\n  +-----------+-----------+-----------+\n  s:5 steps:6 rounds:3 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           | 4   5     |\nB | 7         |     3     |           |\nC |         9 |     8     |           |\n  +-----------+-----------+-----------+\nD |           |     5     |     9   2 |\nE |         8 |           |     6     |\nF |           | 1       7 |     3   4 |\n  +-----------+-----------+-----------+\nG |     2     | 3   6     |     8   7 |\nH | 9         |           | 5         |\nI |     1     | 8         |           |\n  +-----------+-----------+-----------+\n  s:1 steps:7 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           | 1       7 |\nB |     6     |     1   8 |           |\nC |           |           | 4         |\n  +-----------+-----------+-----------+\nD |           |           |     1     |\nE |         9 | 4         |           |\nF |         6 |     7   9 | 5         |\n  +-----------+-----------+-----------+\nG |     2   4 |         3 |           |\nH | 7         |     6     | 2   8     |\nI |     9   5 |         1 |         3 |\n  +-----------+-----------+-----------+\n  s:7 steps:8 rounds:2 digits:24<\/code><\/pre>\n\n\n\n<p>Lis\u00e4\u00e4 oikeasti vaikeita sudokuja, n\u00e4iss\u00e4 on 24 vihjett\u00e4 ja ne ovat miksattuja (&#8211;mix) kauttaviivoja (&#8211;slashes):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     | 9         |     6     |\nB | 9         |         4 | 1         |\nC |         3 |     2     |         7 |\n  +-----------+-----------+-----------+\nD |           |         1 | 9         |\nE |         2 |     3     |         6 |\nF |     3     | 2         |     4     |\n  +-----------+-----------+-----------+\nG |     5     | 8         |     3     |\nH |           |         5 | 2         |\nI |         7 |           |         1 |\n  +-----------+-----------+-----------+\n  s:0 steps:1 rounds:5 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     |         7 |     3     |\nB | 3         | 5         | 1         |\nC |         1 |     9     |         8 |\n  +-----------+-----------+-----------+\nD |     6     |         1 |     4     |\nE |           |     4     |         3 |\nF |           | 6         | 9         |\n  +-----------+-----------+-----------+\nG |           |         6 |     2     |\nH | 4         | 3         | 5         |\nI |         9 |     8     |         7 |\n  +-----------+-----------+-----------+\n  s:1 steps:2 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 1         |     7     | 2         |\nB |         6 |         5 |         1 |\nC |     4     | 6         |     8     |\n  +-----------+-----------+-----------+\nD |         8 |         2 |         9 |\nE |           |     1     | 3         |\nF |     3     |           |     4     |\n  +-----------+-----------+-----------+\nG | 6         |     2     | 7         |\nH |         9 |         6 |         5 |\nI |     7     | 9         |           |\n  +-----------+-----------+-----------+\n  s:2 steps:3 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     5     |         3 |     8     |\nB | 1         | 5         | 9         |\nC |         9 |     7     |         6 |\n  +-----------+-----------+-----------+\nD |     6     |         4 |     1     |\nE |         3 |     5     |         2 |\nF |           | 6         |           |\n  +-----------+-----------+-----------+\nG |     8     |         1 |     4     |\nH | 3         |           | 7         |\nI |         6 |     2     |         9 |\n  +-----------+-----------+-----------+\n  s:3 steps:4 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     7     |     6     |\nB |         4 |         1 |         9 |\nC |     8     | 5         | 3         |\n  +-----------+-----------+-----------+\nD |           |         9 |         5 |\nE | 5         |     3     |     8     |\nF |     9     | 7         | 2         |\n  +-----------+-----------+-----------+\nG |         1 |         7 |         6 |\nH | 6         |     5     |     4     |\nI |     3     | 6         |           |\n  +-----------+-----------+-----------+\n  s:4 steps:5 rounds:3 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 1         | 7         |         2 |\nB |         5 |     6     |           |\nC |     8     |         3 |     9     |\n  +-----------+-----------+-----------+\nD | 5         | 6         |         1 |\nE |     2     |         4 |     8     |\nF |         1 |     8     | 6         |\n  +-----------+-----------+-----------+\nG |     9     |           |     4     |\nH |         3 |     9     | 7         |\nI | 2         | 8         |           |\n  +-----------+-----------+-----------+\n  s:5 steps:6 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 |         9 |     7     |\nB |     8     | 2         | 4         |\nC | 5         |     6     |         8 |\n  +-----------+-----------+-----------+\nD |           | 7         | 8         |\nE |         5 |         4 |     9     |\nF |           |           |         6 |\n  +-----------+-----------+-----------+\nG |     9     | 1         | 7         |\nH | 2         |     9     |         3 |\nI |         3 |         8 |     1     |\n  +-----------+-----------+-----------+\n  s:6 steps:7 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1     |     5     |         8 |\nB | 9         |         2 |           |\nC |           | 7         |     2     |\n  +-----------+-----------+-----------+\nD |         3 | 1         |     4     |\nE | 2         |           | 3         |\nF |     5     |     8     |         6 |\n  +-----------+-----------+-----------+\nG |     6     |     3     |         2 |\nH |         4 | 6         |     1     |\nI | 7         |         8 | 6         |\n  +-----------+-----------+-----------+\n  s:7 steps:8 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     3     |         7 |\nB |         2 | 5         |     3     |\nC |     4     |         7 | 6         |\n  +-----------+-----------+-----------+\nD |     1     |           | 7         |\nE | 3         |     6     |         2 |\nF |         5 | 8         |     9     |\n  +-----------+-----------+-----------+\nG |         1 | 6         |     4     |\nH |     6     |         8 | 1         |\nI | 5         |     2     |           |\n  +-----------+-----------+-----------+\n  s:8 steps:9 rounds:2 digits:24\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     7     |         5 | 6         |\nB |           |     4     |         2 |\nC |         5 | 2         |     7     |\n  +-----------+-----------+-----------+\nD |           | 9         |     1     |\nE |     1     |         7 | 8         |\nF | 4         |     6     |         9 |\n  +-----------+-----------+-----------+\nG | 6         |     1     |         3 |\nH |         8 | 5         |     6     |\nI |           |         9 | 4         |\n  +-----------+-----------+-----------+\n  s:9 steps:10 rounds:2 digits:24<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 oikeasti vaikeita sudokuja (25 vihjett\u00e4)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         9 | 1         |     7   3 |\nB |           |     5   2 |     8     |\nC | 8         | 3         |           |\n  +-----------+-----------+-----------+\nD |     6     |         7 |         5 |\nE |           |         1 |           |\nF | 1         | 4         |         8 |\n  +-----------+-----------+-----------+\nG | 5         | 7         |           |\nH |     7     |     2     | 6         |\nI |     4     | 8       9 | 2         |\n  +-----------+-----------+-----------+\n  s:0 steps:1 rounds:3 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 9       2 |           |           |\nB |         5 |         4 | 9         |\nC | 8       1 |         6 |         3 |\n  +-----------+-----------+-----------+\nD | 6         |     7     |           |\nE |     7   4 |           |     9     |\nF |         3 | 8         |     5     |\n  +-----------+-----------+-----------+\nG | 2         | 6   9     |           |\nH |           |         1 | 8       7 |\nI |           |     4     | 2         |\n  +-----------+-----------+-----------+\n  s:1 steps:2 rounds:4 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           | 3         |\nB |           |     3     | 8   2     |\nC | 4       8 |           |     5   1 |\n  +-----------+-----------+-----------+\nD |         5 |     4   1 |         6 |\nE | 7         | 9         |           |\nF |           |           |         3 |\n  +-----------+-----------+-----------+\nG |           |     6   8 |     3     |\nH | 5   8   2 |           |           |\nI |         9 | 4   7     |         8 |\n  +-----------+-----------+-----------+\n  s:2 steps:3 rounds:3 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |           |           |\nB | 1   2     |     5     | 9   4     |\nC | 4         |         7 |           |\n  +-----------+-----------+-----------+\nD |           | 1         | 8         |\nE |     1     | 7         |         6 |\nF |     3     | 4         |     2     |\n  +-----------+-----------+-----------+\nG | 3         |     9     | 2         |\nH |     9     | 2   4     |     5   3 |\nI |           | 3         |           |\n  +-----------+-----------+-----------+\n  s:3 steps:4 rounds:2 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         4 |     2     |           |\nB | 1   6     | 8   9   4 |           |\nC |         3 | 1         |           |\n  +-----------+-----------+-----------+\nD |     8     | 9   5     | 3         |\nE |     5     | 7   4     |           |\nF |           |           |     9   2 |\n  +-----------+-----------+-----------+\nG | 9   2     |     8     |           |\nH |         6 |           |           |\nI |           |     7     | 2       5 |\n  +-----------+-----------+-----------+\n  s:4 steps:5 rounds:3 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         3 |           |\nB |     9     | 2   6     |           |\nC |     5     | 1   9     | 8         |\n  +-----------+-----------+-----------+\nD | 2         | 4         |           |\nE |     8   5 |     7     |     4   6 |\nF |           |           | 2       8 |\n  +-----------+-----------+-----------+\nG |         4 |           | 1   7     |\nH |         8 |           |           |\nI | 6   1     |         7 |         2 |\n  +-----------+-----------+-----------+\n  s:5 steps:6 rounds:4 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     3   9 | 2   1     |\nB |           |     8     |     4     |\nC |         7 |           | 3         |\n  +-----------+-----------+-----------+\nD |     4   1 |     5     | 8         |\nE |     2   3 |         7 |           |\nF | 9         |           |           |\n  +-----------+-----------+-----------+\nG |           |           | 7       2 |\nH | 8   5     |           | 1         |\nI |         2 |         1 | 5       4 |\n  +-----------+-----------+-----------+\n  s:6 steps:7 rounds:2 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3   2     |         1 |         9 |\nB |           | 4         | 6         |\nC |         8 |     2   6 |           |\n  +-----------+-----------+-----------+\nD |           |         3 |           |\nE | 5       7 |     1     | 8         |\nF |           |           | 2   6     |\n  +-----------+-----------+-----------+\nG |         5 | 9   6     | 3         |\nH |         3 |           | 9       7 |\nI |           |         7 | 4         |\n  +-----------+-----------+-----------+\n  s:7 steps:8 rounds:3 digits:25\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         9 |         6 |\nB | 3   4     |           | 5         |\nC |     7   6 | 8         |           |\n  +-----------+-----------+-----------+\nD |     5     |     2   4 |           |\nE |           | 6         |           |\nF | 7         |           | 6       4 |\n  +-----------+-----------+-----------+\nG |     1     |           |     7   3 |\nH | 4         |     3   1 | 2         |\nI |           |     5     | 9   1     |\n  +-----------+-----------+-----------+\n<\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 lis\u00e4\u00e4 oikeasti vaikeita sudokuja: n\u00e4iss\u00e4 steps vaihtelee kuuden ja kahdentoista v\u00e4lill\u00e4 ja clues (digits) vaihtelee 23 ja 30 v\u00e4lill\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 8         |     9   6 |\nB |           | 3         | 1   2     |\nC | 6       9 |         7 |           |\n  +-----------+-----------+-----------+\nD | 7   5     | 4         | 9   6     |\nE |     4   8 | 6       1 |           |\nF | 2         |     9     |     4     |\n  +-----------+-----------+-----------+\nG |         7 |         6 |     3     |\nH | 5       2 |           | 6       9 |\nI |         6 |           | 8         |\n  +-----------+-----------+-----------+\n  s:8 gu:29 st:6 ro:2 clues:30\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1   9 | 5   4     | 7         |\nB |     6   8 |     3     |     2     |\nC |           | 8   2     |         9 |\n  +-----------+-----------+-----------+\nD |     7     |     8     | 3       6 |\nE |         4 |         5 |           |\nF |           |     6     |         1 |\n  +-----------+-----------+-----------+\nG |     5     |     9     |         3 |\nH |     2   7 |         3 |     9   4 |\nI |           |           | 8         |\n  +-----------+-----------+-----------+\n  s:5 gu:31 st:6 ro:2 clues:29\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         6 | 9   7     | 5         |\nB | 9         | 8       1 |           |\nC |         8 | 2   6     |           |\n  +-----------+-----------+-----------+\nD |           |     8     | 9   3     |\nE |           | 4         |         6 |\nF |     4   9 | 3         |     8   7 |\n  +-----------+-----------+-----------+\nG |         7 |     4   8 |           |\nH |           | 6         |           |\nI | 3         | 7   2     |         5 |\n  +-----------+-----------+-----------+\n  s:5 gu:35 st:6 ro:2 clues:28\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     8     |           |         7 |\nB |     4   5 |         9 |     2     |\nC |         9 | 6       2 |           |\n  +-----------+-----------+-----------+\nD |     7   3 |           |     4     |\nE | 6   9     | 3         |     7   5 |\nF |           | 2   5     |           |\n  +-----------+-----------+-----------+\nG |     6   4 |     2     |           |\nH |           |     6   3 |           |\nI |     2     | 5         |         1 |\n  +-----------+-----------+-----------+\n  s:26 gu:20 st:6 ro:3 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8         | 3         |     5     |\nB |         9 |     1     |         6 |\nC |     5     |         4 | 9         |\n  +-----------+-----------+-----------+\nD | 3         | 8         |     2     |\nE |     8     |         5 | 1         |\nF |         1 |     3     |         7 |\n  +-----------+-----------+-----------+\nG |         7 |     2     |         8 |\nH | 6         | 9         |     1     |\nI |     4     |         3 | 6         |\n  +-----------+-----------+-----------+\n  s:23 gu:21 st:6 ro:3 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 5         |     3     | 2         |\nB |         4 |         9 |         8 |\nC |     9     | 4         |     6     |\n  +-----------+-----------+-----------+\nD |         9 |         8 |         7 |\nE | 2         |     7     | 5         |\nF |     7     | 3         |     8     |\n  +-----------+-----------+-----------+\nG | 7         |     8     | 6         |\nH |         2 |         3 |           |\nI |     6     | 1         |     4     |\n  +-----------+-----------+-----------+\n  s:18 gu:13 st:6 ro:3 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4         |           | 3   7     |\nB | 2   7     |     9   3 |           |\nC |           |           |           |\n  +-----------+-----------+-----------+\nD |         5 |         7 | 2         |\nE | 1         |         8 |           |\nF |     6   2 | 9         | 8         |\n  +-----------+-----------+-----------+\nG |           |           | 6       5 |\nH |           | 1       2 | 9   4   8 |\nI |           | 3       6 | 7         |\n  +-----------+-----------+-----------+\n  s:4 gu:18 st:6 ro:4 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         |     2     |     5     |\nB |     3   8 |           | 6         |\nC | 6   9     |         1 |     7     |\n  +-----------+-----------+-----------+\nD |           |         6 |           |\nE |         4 | 7         |           |\nF |     8     |     3     | 7       1 |\n  +-----------+-----------+-----------+\nG |           |         2 | 5         |\nH |     5   7 |           | 1       3 |\nI |           |     9     |     4     |\n  +-----------+-----------+-----------+\n  s:34 gu:15 st:6 ro:3 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         4 |         7 |         3 |\nB |     8     | 1         |     5     |\nC | 6         |     3     | 9         |\n  +-----------+-----------+-----------+\nD |     1     | 2         |           |\nE |         3 |         9 |         2 |\nF | 5         |     6     | 1         |\n  +-----------+-----------+-----------+\nG |         8 |           |         6 |\nH |     3     | 6         |     8     |\nI | 1         |     8     | 7         |\n  +-----------+-----------+-----------+\n  s:15 gu:17 st:6 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 7   1   5 |     8   3 |\nB |         1 |           | 7       2 |\nC |           |         3 |           |\n  +-----------+-----------+-----------+\nD |           | 8         |     9     |\nE | 5         |     3     |           |\nF |           |         4 | 1         |\n  +-----------+-----------+-----------+\nG | 2       9 |           |         6 |\nH |     5   3 |     6     | 9   2     |\nI |           |     4     |           |\n  +-----------+-----------+-----------+\n  s:11 gu:37 st:6 ro:3 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     | 6         |         9 |\nB |           |         1 |     3     |\nC |         2 |     8     | 1         |\n  +-----------+-----------+-----------+\nD | 2         |           |     1     |\nE |         7 |     6     | 4         |\nF |           | 5         |         8 |\n  +-----------+-----------+-----------+\nG |         3 |     4     | 8         |\nH |     6     | 9         |         2 |\nI | 1         |         3 |     5     |\n  +-----------+-----------+-----------+\n  s:1 gu:38 st:6 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     2     |           |\nB |     8     | 9         |     7     |\nC |         9 | 5         | 1   2     |\n  +-----------+-----------+-----------+\nD | 8         |           |           |\nE |     3   5 |           |           |\nF |     1   4 |     3     | 6         |\n  +-----------+-----------+-----------+\nG |           |           |     1     |\nH | 7         | 4   5     |           |\nI | 3         | 7         |     6   8 |\n  +-----------+-----------+-----------+\n  s:2 gu:58 st:6 ro:1 clues:23\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     8     |         5 |\nB |           | 3         |           |\nC |         9 |         2 |     6     |\n  +-----------+-----------+-----------+\nD |     4     |     5     |         8 |\nE | 2         | 6         | 3         |\nF |         5 |         9 |     1     |\n  +-----------+-----------+-----------+\nG |     7     |     1     |         2 |\nH |         6 |           |     8     |\nI | 8         | 7         | 4         |\n  +-----------+-----------+-----------+\n  s:0 gu:89 st:6 ro:2 clues:23\n  \n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 2       7 | 5         |     8   9 |\nB |           |           |         2 |\nC |           | 8         | 6         |\n  +-----------+-----------+-----------+\nD | 9   3     |           | 2       1 |\nE |     2     | 3         | 9       5 |\nF |         6 |     1     |         8 |\n  +-----------+-----------+-----------+\nG | 4   8     | 6   2     |     9     |\nH | 3       9 |         4 |         6 |\nI |           | 9   7     |           |\n  +-----------+-----------+-----------+\n  s:1 gu:46 st:7 ro:2 clues:30\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 6         | 8         |         1 |\nB | 2   5     |           |         4 |\nC | 9       1 |         5 |     2     |\n  +-----------+-----------+-----------+\nD |           |     3     | 9   4     |\nE | 3       4 |           |           |\nF |     9   6 |     5   7 |           |\n  +-----------+-----------+-----------+\nG | 4         |     8   6 |         3 |\nH | 7         | 5   1     | 4         |\nI |           |     7     | 8         |\n  +-----------+-----------+-----------+\n  s:0 gu:22 st:7 ro:2 clues:29\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 6         |         7 | 1       3 |\nB |     9     |     8     |           |\nC |     3     | 1         |     6     |\n  +-----------+-----------+-----------+\nD |         3 | 2         |           |\nE | 8       6 |     3     | 2         |\nF |     4     |     6   5 |     8   1 |\n  +-----------+-----------+-----------+\nG |         7 |     4     |         8 |\nH |     2     |           |         5 |\nI |           | 3         |     1   2 |\n  +-----------+-----------+-----------+\n  s:0 gu:26 st:7 ro:2 clues:28\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     3     |     5     |         7 |\nB | 1         | 7         | 8         |\nC |         8 |         1 |     4     |\n  +-----------+-----------+-----------+\nD |     8     |     1     |         6 |\nE | 3         | 2         | 7         |\nF |         2 |         5 |     1     |\n  +-----------+-----------+-----------+\nG |     6     |     2     |         1 |\nH |         3 |         8 |     5     |\nI | 2         | 6         | 9         |\n  +-----------+-----------+-----------+\n  s:56 gu:33 st:7 ro:2 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     6   8 | 7   2     |           |\nB | 7         |     4   5 |     9     |\nC |           | 6         |     3     |\n  +-----------+-----------+-----------+\nD |     7     | 1         |     8     |\nE | 6       1 |         4 |     2   5 |\nF | 5       3 |           |           |\n  +-----------+-----------+-----------+\nG |     3     |           | 4       9 |\nH | 1         | 5   9     |           |\nI |           |           |         2 |\n  +-----------+-----------+-----------+\n  s:3 gu:114 st:7 ro:3 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 | 7         |     6     |\nB |     3     |         5 |         8 |\nC | 5         |     4     | 1         |\n  +-----------+-----------+-----------+\nD | 9         |     1     | 6         |\nE |         3 | 9         |     2     |\nF |     4     |         7 |         3 |\n  +-----------+-----------+-----------+\nG |         4 | 1         |     9     |\nH | 1         |     7     | 3         |\nI |     8     |         3 |           |\n  +-----------+-----------+-----------+\n  s:17 gu:62 st:7 ro:3 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4         |     2     |           |\nB |           |           | 7         |\nC |           |         3 | 9       1 |\n  +-----------+-----------+-----------+\nD | 1   5     | 6         | 8       4 |\nE |           |     5     | 3       9 |\nF |           | 4         | 2         |\n  +-----------+-----------+-----------+\nG | 3         |     1   7 |           |\nH | 6   8     | 5         |     2     |\nI |         2 |     8   6 |           |\n  +-----------+-----------+-----------+\n  s:2 gu:36 st:7 ro:3 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 9   6     |     4   8 |         3 |\nB |     2     | 6         | 9         |\nC |         1 | 5         |           |\n  +-----------+-----------+-----------+\nD |     9     |           |         6 |\nE |           |     8     |         2 |\nF |     4     |         5 |     9   1 |\n  +-----------+-----------+-----------+\nG | 2         |           | 3   7     |\nH |           | 7         |     4     |\nI | 4         |           |         8 |\n  +-----------+-----------+-----------+\n  s:15 gu:75 st:7 ro:4 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 |         9 |     6     |\nB |           |     3     | 1         |\nC | 3         | 2         |         8 |\n  +-----------+-----------+-----------+\nD |         6 |         1 |     9     |\nE |     7     |     6     | 5         |\nF | 4         | 5         |         1 |\n  +-----------+-----------+-----------+\nG |     1     |     2     | 9         |\nH | 6         | 1         |         7 |\nI |         8 |         3 |           |\n  +-----------+-----------+-----------+\n  s:19 gu:50 st:7 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         9 |           | 5         |\nB |           | 3         |           |\nC | 1         | 9   6     |           |\n  +-----------+-----------+-----------+\nD |         1 |     8     |           |\nE | 2         |         6 |     4   8 |\nF |     4     | 1       5 |     7     |\n  +-----------+-----------+-----------+\nG |     6     |           |         2 |\nH | 3         |           | 6       4 |\nI | 4       2 |           | 9         |\n  +-----------+-----------+-----------+\n  s:3 gu:53 st:7 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         4 |         7 |\nB |         9 | 3         | 2         |\nC |     2     |     8     |     5     |\n  +-----------+-----------+-----------+\nD |     1     |     5     |     9     |\nE |         4 | 6         | 5         |\nF | 6         |         9 |         2 |\n  +-----------+-----------+-----------+\nG |     7     |     1     |     2     |\nH |         3 |           | 4         |\nI | 5         |         7 |           |\n  +-----------+-----------+-----------+\n  s:18 gu:62 st:7 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4   9   2 |     6     |     5     |\nB |         5 |         9 |     1     |\nC |     1     |     5     |           |\n  +-----------+-----------+-----------+\nD |         3 |           |         7 |\nE |     2     | 4   3     | 9   8   5 |\nF | 9         |           | 6         |\n  +-----------+-----------+-----------+\nG | 3         | 6   1     |           |\nH | 1         |     2     | 4         |\nI | 2       8 | 7         | 5         |\n  +-----------+-----------+-----------+\n  s:0 gu:22 st:8 ro:2 clues:30\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           | 1         |\nB | 3       2 |         4 |         6 |\nC | 1         | 6   3   2 |     5     |\n  +-----------+-----------+-----------+\nD | 2       5 |     6     |         8 |\nE |     9   6 |           |     4     |\nF | 8         |         7 |           |\n  +-----------+-----------+-----------+\nG | 5   8   3 |     4     |         7 |\nH |           |     7     |           |\nI | 6         | 5       1 |     9     |\n  +-----------+-----------+-----------+\n  s:0 gu:18 st:8 ro:2 clues:29\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8   5     |           |         9 |\nB |         6 |     7     |           |\nC | 9   2     |     6     |         4 |\n  +-----------+-----------+-----------+\nD |         8 | 7         |         2 |\nE |         3 | 2       4 |           |\nF |     9     |         1 | 3         |\n  +-----------+-----------+-----------+\nG |         9 |     2   8 | 4       7 |\nH |         4 |           | 8         |\nI | 6         |     4     | 1         |\n  +-----------+-----------+-----------+\n  s:1 gu:20 st:8 ro:2 clues:28\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |         1 | 6         |\nB |           |           |           |\nC | 5       9 | 4   7     | 1         |\n  +-----------+-----------+-----------+\nD | 8   3     |         7 | 2   6     |\nE |         5 |     2     |     3     |\nF |           |           | 7         |\n  +-----------+-----------+-----------+\nG |         7 | 6         |     2     |\nH |           |     9     | 3   4     |\nI | 4   8   6 |         2 |           |\n  +-----------+-----------+-----------+\n  s:5 gu:18 st:8 ro:3 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     1     |     6     |         8 |\nB | 5         |         1 | 3         |\nC |         3 | 2         |     9     |\n  +-----------+-----------+-----------+\nD |         2 | 5         |     1     |\nE | 1         |         2 | 4         |\nF |     7     |     8     |         9 |\n  +-----------+-----------+-----------+\nG |     3     |     2     |         1 |\nH |         6 | 3         |     7     |\nI | 8         |         5 | 9         |\n  +-----------+-----------+-----------+\n  s:0 gu:33 st:8 ro:2 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8         | 6       4 | 3       2 |\nB |           | 7         |           |\nC |         6 | 2         | 4   5   8 |\n  +-----------+-----------+-----------+\nD |     8     | 4         |           |\nE | 9         | 3         |     4     |\nF |           |         5 | 9         |\n  +-----------+-----------+-----------+\nG |     1   2 | 5         |     3     |\nH |           |           | 5         |\nI |         5 |         7 | 6         |\n  +-----------+-----------+-----------+\n  s:2 gu:57 st:8 ro:2 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 1         | 9         |         2 |\nB |         9 |         2 |     3     |\nC |     4     |     6     | 8         |\n  +-----------+-----------+-----------+\nD | 4         | 6         |         8 |\nE |         7 |         1 |     2     |\nF |           |     3     | 9         |\n  +-----------+-----------+-----------+\nG |         1 |         6 |     9     |\nH |     7     |     5     | 1         |\nI | 6         | 3         |         4 |\n  +-----------+-----------+-----------+\n  s:0 gu:35 st:8 ro:2 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     3     |     7     | 6         |\nB | 4         |         9 |     8     |\nC |           | 5         |         4 |\n  +-----------+-----------+-----------+\nD |         5 | 6         |         3 |\nE | 3         |         7 |     9     |\nF |     6     |     5     | 7         |\n  +-----------+-----------+-----------+\nG | 5         |         3 |     6     |\nH |     2     |     8     | 9         |\nI |         1 |           |         8 |\n  +-----------+-----------+-----------+\n  s:0 gu:19 st:8 ro:3 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 3       9 |     1     |\nB | 8         | 7         |     9     |\nC |     4     |     5   2 |           |\n  +-----------+-----------+-----------+\nD |     9   5 |           |         8 |\nE | 3       7 |           |     6     |\nF | 1   6     |           |         3 |\n  +-----------+-----------+-----------+\nG |         9 | 8   7     |           |\nH |           |           | 7   4     |\nI |           | 5         | 6         |\n  +-----------+-----------+-----------+\n  s:10 gu:80 st:8 ro:3 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         7 | 4         |         5 |\nB |     1     |     5     | 8         |\nC | 6         |         9 |     7     |\n  +-----------+-----------+-----------+\nD |           |         7 |     4     |\nE |     3     |     8     | 6         |\nF |         5 | 6         |         2 |\n  +-----------+-----------+-----------+\nG |     7     |     1     | 5         |\nH |         3 | 8         |         6 |\nI | 1         |           |           |\n  +-----------+-----------+-----------+\n  s:1 gu:39 st:8 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 2         |           |\nB |     2   5 |           | 6   3     |\nC |           |     5     |           |\n  +-----------+-----------+-----------+\nD | 6         |           |     8   9 |\nE |         8 |     3     | 1   6     |\nF |     7     |           |     2     |\n  +-----------+-----------+-----------+\nG |           |     8   6 | 3         |\nH |           |     1   5 |         8 |\nI | 9         | 4       3 |           |\n  +-----------+-----------+-----------+\n  s:12 gu:78 st:8 ro:3 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         4 |         5 |         2 |\nB |     9     |     7     |     5     |\nC | 7         |           | 3         |\n  +-----------+-----------+-----------+\nD |         1 |         2 |         8 |\nE |     3     |     9     |     1     |\nF |           | 8         | 6         |\n  +-----------+-----------+-----------+\nG |           |         7 |         5 |\nH |     6     |     4     |           |\nI | 8         | 5         | 9         |\n  +-----------+-----------+-----------+\n  s:4 gu:79 st:8 ro:2 clues:23\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           |           |\nB |     8     |     6     | 4   1     |\nC | 5   3     |     1     | 2       6 |\n  +-----------+-----------+-----------+\nD | 9   4     |     5   1 |           |\nE |     2     | 4         | 9   5     |\nF | 7         | 3   2     | 6   4     |\n  +-----------+-----------+-----------+\nG |           |         8 | 1         |\nH | 8   1     |           |     6     |\nI | 4   7     |           |         8 |\n  +-----------+-----------+-----------+\n  s:2 gu:61 st:9 ro:3 clues:30\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4         |         7 |     1   5 |\nB | 6   7     | 2       5 |           |\nC |           | 8         | 2         |\n  +-----------+-----------+-----------+\nD | 5         |         9 | 7       6 |\nE |     6     |     7     |     4     |\nF |     3     | 4         | 1       8 |\n  +-----------+-----------+-----------+\nG | 7       3 | 6         |           |\nH | 2   8     |         3 | 9         |\nI |           |         8 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:19 st:9 ro:2 clues:29\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3         |     1   9 |           |\nB |         4 | 2         |     1     |\nC | 2         | 7         |         6 |\n  +-----------+-----------+-----------+\nD |         3 | 5   9     |     6     |\nE |           |     8     | 3   7     |\nF |           | 6         |     4   1 |\n  +-----------+-----------+-----------+\nG | 8         | 3   7   5 |           |\nH |         2 |           |           |\nI | 1   7     |         8 | 6         |\n  +-----------+-----------+-----------+\n  s:0 gu:23 st:9 ro:3 clues:28\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           | 2         | 8         |\nB |           | 1   4     |     2   3 |\nC |           |           |           |\n  +-----------+-----------+-----------+\nD |     9     | 5       4 |         1 |\nE |     3     |           |         9 |\nF |         1 | 8   9     |     7     |\n  +-----------+-----------+-----------+\nG | 9       4 | 3         | 6         |\nH |     8   3 |     7     |     4     |\nI |     1   5 |         2 |           |\n  +-----------+-----------+-----------+\n  s:0 gu:133 st:9 ro:2 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 4         | 3         | 1         |\nB |         1 |     9     |         6 |\nC |     9     |         1 |     5     |\n  +-----------+-----------+-----------+\nD | 6         | 8         | 2         |\nE |     5     |         7 |     3     |\nF |         9 |     4     |         8 |\n  +-----------+-----------+-----------+\nG | 9         | 7         | 8         |\nH |         7 |     3     |         1 |\nI |     2     |         9 |     4     |\n  +-----------+-----------+-----------+\n  s:1 gu:27 st:9 ro:4 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           | 7         |\nB |     6     |         9 |         4 |\nC |           |           |     5   2 |\n  +-----------+-----------+-----------+\nD |     4   3 |           |           |\nE | 6       5 |         3 | 1         |\nF | 8         |         6 |     7     |\n  +-----------+-----------+-----------+\nG | 4         |     6     |     2   7 |\nH | 3         |     2     |           |\nI | 7       8 |         4 | 3       6 |\n  +-----------+-----------+-----------+\n  s:2 gu:35 st:9 ro:3 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         3 |         4 |         6 |\nB |     9     |     1     |     2     |\nC | 6         | 9         | 5         |\n  +-----------+-----------+-----------+\nD |         5 |         8 |         4 |\nE |     1     |     9     |     5     |\nF | 2         | 3         | 1         |\n  +-----------+-----------+-----------+\nG |         7 |         9 |         1 |\nH |           |     3     |     9     |\nI | 1         | 4         | 3         |\n  +-----------+-----------+-----------+\n  s:3 gu:30 st:9 ro:2 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 2       9 |         8 |     3     |\nB |         1 |           | 4         |\nC | 3   5     | 1         |         6 |\n  +-----------+-----------+-----------+\nD |           |           |           |\nE |           | 7   5     | 6         |\nF | 4         |         3 |           |\n  +-----------+-----------+-----------+\nG |           | 8         |     4     |\nH |     2   5 | 4       9 |         7 |\nI | 6         |           | 9       2 |\n  +-----------+-----------+-----------+\n  s:11 gu:54 st:9 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         1 |     4     |\nB |         7 |     9     | 8         |\nC |     2     | 8         |         5 |\n  +-----------+-----------+-----------+\nD |         9 |     1     | 2         |\nE |     8     | 2         |         6 |\nF | 4         |         5 |     7     |\n  +-----------+-----------+-----------+\nG |           | 7         |         1 |\nH | 6         |         3 |     2     |\nI |         4 |     5     | 3         |\n  +-----------+-----------+-----------+\n  s:0 gu:104 st:9 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |           |           |\nB |           |     1     |         2 |\nC | 1   2   6 |     5     | 4       8 |\n  +-----------+-----------+-----------+\nD |     4     | 6         |           |\nE |     9     |           |         6 |\nF |     6   3 | 7       9 |     5     |\n  +-----------+-----------+-----------+\nG |         5 |           | 8         |\nH |     1     |           | 3       9 |\nI |     7     |     2     |           |\n  +-----------+-----------+-----------+\n  s:10 gu:257 st:9 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3         |           |     9     |\nB |         4 |     1     | 5         |\nC |     6     | 7         |           |\n  +-----------+-----------+-----------+\nD |         3 |     4     | 7         |\nE |     5     | 9         |         3 |\nF | 2         |         5 |     8     |\n  +-----------+-----------+-----------+\nG |     2     | 6         |         7 |\nH | 4         |         9 |     2     |\nI |         8 |           | 3         |\n  +-----------+-----------+-----------+\n  s:6 gu:77 st:9 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         8 |         5 |           |\nB |     6     |     2     |     3     |\nC | 3         | 1         |         7 |\n  +-----------+-----------+-----------+\nD |           |         7 | 3         |\nE |     5     |     6     |     9     |\nF | 1         | 9         |         8 |\n  +-----------+-----------+-----------+\nG | 7         | 3         |         9 |\nH |     1     |           |     4     |\nI |           |         2 | 6         |\n  +-----------+-----------+-----------+\n  s:4 gu:43 st:9 ro:2 clues:23\n  \n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     5     |     3   6 |           |\nB |         3 |           |           |\nC | 6       9 | 7       1 | 3         |\n  +-----------+-----------+-----------+\nD |         1 |         2 |     8     |\nE |     9     |         8 | 2       7 |\nF | 2         |     5     |     6     |\n  +-----------+-----------+-----------+\nG | 4   1     | 2         | 7   3     |\nH | 7         | 4   6     |           |\nI |           |           |           |\n  +-----------+-----------+-----------+\n  s:2 gu:52 st:10 ro:2 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 7         |         2 |     1     |\nB |           |           |     9   5 |\nC |         5 |     7     |     6     |\n  +-----------+-----------+-----------+\nD |           | 3       6 |         8 |\nE |           |         4 |         1 |\nF |         2 |     8     | 6   3     |\n  +-----------+-----------+-----------+\nG |     9   4 |         7 | 3         |\nH |     3     | 4   5     |         7 |\nI | 8         |           |           |\n  +-----------+-----------+-----------+\n  s:5 gu:36 st:10 ro:2 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 3         |     9     |         4 |\nB |         8 | 7         | 5         |\nC |     9     |         5 |           |\n  +-----------+-----------+-----------+\nD |     7     |         9 |     3     |\nE | 1         |     5     |         6 |\nF |         4 | 6         | 8         |\n  +-----------+-----------+-----------+\nG |           |         4 |     6     |\nH |         5 | 9         | 1         |\nI | 2         |     7     |         3 |\n  +-----------+-----------+-----------+\n  s:51 gu:200 st:10 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 9   1     |         2 |           |\nB |           |         1 |     3     |\nC | 7       8 |           |     2     |\n  +-----------+-----------+-----------+\nD | 5         | 4         | 2       9 |\nE |           | 9       6 |           |\nF |           |           | 3       7 |\n  +-----------+-----------+-----------+\nG |         6 |           | 1         |\nH | 4         |         9 |           |\nI |     8     |     7   4 |         3 |\n  +-----------+-----------+-----------+\n  s:3 gu:73 st:10 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     9     | 5         | 2         |\nB | 1         |     8     |     3     |\nC |         6 |         7 |           |\n  +-----------+-----------+-----------+\nD | 5         |     7     |     9     |\nE |           | 6         | 4         |\nF |         7 |         1 |         2 |\n  +-----------+-----------+-----------+\nG | 8         |     1     |     2     |\nH |     7     | 4         |           |\nI |         4 |         3 |         9 |\n  +-----------+-----------+-----------+\n  s:1 gu:40 st:10 ro:2 clues:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |         2 | 1         |\nB | 1         |     6     |         8 |\nC |         9 |           |     2     |\n  +-----------+-----------+-----------+\nD |         5 | 9         |     6     |\nE |     4     |         7 | 2         |\nF |           |           |         4 |\n  +-----------+-----------+-----------+\nG | 7         |     5     |         1 |\nH |         2 | 3         |     4     |\nI |     5     |         4 | 8         |\n  +-----------+-----------+-----------+\n  s:0 gu:104 st:10 ro:2 clues:23\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 8         |         3 |         9 |\nB |         3 | 2         | 1         |\nC |     1     |     5     |     8     |\n  +-----------+-----------+-----------+\nD |     9     |     3     |     6     |\nE |         8 | 9         | 2         |\nF | 4         |         2 |         1 |\n  +-----------+-----------+-----------+\nG |     8     |     4     |     2     |\nH |         6 | 3         | 8         |\nI | 9         |         5 |         6 |\n  +-----------+-----------+-----------+\n  s:12 gu:75 st:11 ro:3 clues:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         7 |         6 |         4 |\nB |     5     |     7     |     8     |\nC | 1         | 8         | 5         |\n  +-----------+-----------+-----------+\nD |         5 |         3 |         9 |\nE |     1     |     8     |     3     |\nF | 3         | 9         | 4         |\n  +-----------+-----------+-----------+\nG |         2 |         9 |         7 |\nH |     9     |     2     |     5     |\nI | 7         | 6         | 9         |\n  +-----------+-----------+-----------+\n  s:2 guesses:68 st:11 ro:2 di:27\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     8     |     3     | 2         |\nB | 1         |         2 |         3 |\nC |         2 | 7         |     1     |\n  +-----------+-----------+-----------+\nD |         9 | 6         |     5     |\nE | 8         |         4 |         9 |\nF |     5     |           | 4         |\n  +-----------+-----------+-----------+\nG | 9         |         6 |         1 |\nH |         3 | 9         |     6     |\nI |     2     |     4     | 9         |\n  +-----------+-----------+-----------+\n  s:0 gu:61 st:11 ro:1 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         5 |           |         4 |\nB |     2     | 4         | 1         |\nC | 1         |         3 |     7     |\n  +-----------+-----------+-----------+\nD |     8     | 7         | 4         |\nE | 6         |         2 |     1     |\nF |         2 |     1     |         3 |\n  +-----------+-----------+-----------+\nG |     6     | 2         | 5         |\nH |         9 |     8     |         2 |\nI | 2         |         7 |     8     |\n  +-----------+-----------+-----------+\n  s:4 gu:132 st:11 ro:2 clues:26\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         5 |           |     8     |\nB |     8     |     5     | 1         |\nC | 9         |         3 |         5 |\n  +-----------+-----------+-----------+\nD | 3         |         7 |         1 |\nE |     7     |     2     | 3         |\nF |         6 | 3         |     2     |\n  +-----------+-----------+-----------+\nG |     6     |     4     | 5         |\nH | 1         |           |         4 |\nI |         7 | 8         |     9     |\n  +-----------+-----------+-----------+\n  s:9 gu:73 st:11 ro:2 clues:25\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     5     |         3 |           |\nB | 4         |     5     |         3 |\nC |         3 | 4         |     6     |\n  +-----------+-----------+-----------+\nD |         6 | 7         |     1     |\nE |     1     |           | 9         |\nF | 5         |     2     |         8 |\n  +-----------+-----------+-----------+\nG | 7         |     9     |         4 |\nH |         9 |           |     3     |\nI |     6     |         2 | 8         |\n  +-----------+-----------+-----------+\n  s:0 guesses:76 st:11 ro:2 di:24\n\nA   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         2 |         7 | 6         |\nB |     6     |           |         9 |\nC | 4         |           |     3     |\n  +-----------+-----------+-----------+\nD |           | 1         |         6 |\nE |         3 |         2 | 4         |\nF | 5         |     9     |     7     |\n  +-----------+-----------+-----------+\nG | 8         |     2     |     6     |\nH |         7 |         8 | 1         |\nI |     2     | 9         |         5 |\n  +-----------+-----------+-----------+\n  s:0 guesses:194 st:12 ro:2 di:24\n\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |     4     |     9     | 5       7 |\nB |         5 |           |     1     |\nC | 9         | 5   2     |           |\n  +-----------+-----------+-----------+\nD | 8       4 |     5   2 | 7   9     |\nE | 1         |           |           |\nF |         2 | 4         |     6     |\n  +-----------+-----------+-----------+\nG |           | 2   8     | 3         |\nH |         8 | 7         |     4     |\nI |           |         3 |         9 |\n  +-----------+-----------+-----------+\n  s:5 guesses:44 st:12 ro:4 di:27<\/code><\/pre>\n\n\n\n<p>L\u00f6ysin kolmannen steps:12 sudokun: N\u00e4m\u00e4 ovat vaikeimpia t\u00e4h\u00e4n asti l\u00f6yt\u00e4mist\u00e4ni.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |         5 | 7   9     |         2 |\nB | 2   9     | 3         |           |\nC | 8         |           |         9 |\n  +-----------+-----------+-----------+\nD |         9 | 2         | 5         |\nE |           | 8   4     | 7         |\nF |     4     |           |         1 |\n  +-----------+-----------+-----------+\nG | 9         |           |           |\nH |         4 | 5   8     |     6     |\nI | 1         |         3 | 8         |\n  +-----------+-----------+-----------+\n  s:3 gu:184 st:12 ro:2 clues:25<\/code><\/pre>\n\n\n\n<p>My\u00f6s simplesolven rounds: yritt\u00e4\u00e4 kuvata sudokun vaikeutta, mutta siit\u00e4 huolimatta n\u00e4m\u00e4 ratkeavat yksinkertaisilla menetelmill\u00e4 (katso simplesolve): seuraavassa muutamia:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |     7     |     9     | 5       2 |\nB | 8         | 5       1 |           |\nC |           |           |         1 |\n  +-----------+-----------+-----------+\nD |           |           | 3   7     |\nE | 2         |     8     |           |\nF |         4 |           |         9 |\n  +-----------+-----------+-----------+\nG |           |         7 | 6         |\nH |     9   5 |         3 | 8         |\nI |         8 | 4         |     1     |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:12 digits:23\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA |         7 | 9       5 |           |\nB |           | 8       1 |           |\nC |           | 4   6     |     9   7 |\n  +-----------+-----------+-----------+\nD | 8         |           |     6     |\nE |         6 |           | 7       3 |\nF |           | 6   8     | 9       4 |\n  +-----------+-----------+-----------+\nG | 1         | 3         |     4     |\nH | 6       3 | 2       9 |           |\nI |         2 |           |     5     |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:12 digits:27\n    A   B   C   D   E   F   G   H   I\n  +-----------+-----------+-----------+\nA | 9         |         6 | 5         |\nB |           | 1         |     6     |\nC | 3   6     |     7     | 8         |\n  +-----------+-----------+-----------+\nD |         4 | 6       8 |     7     |\nE | 7       5 | 2   1   4 | 3       6 |\nF |     8     |           | 1         |\n  +-----------+-----------+-----------+\nG | 4         | 3       2 |           |\nH |           |           |     3   9 |\nI |           |     6     | 2         |\n  +-----------+-----------+-----------+\n  s:0 steps:0 rounds:12 digits:29<\/code><\/pre>\n\n\n\n<p>Seuraavassa sudokuohjelman osien l\u00e4pik\u00e4yminen, ensimm\u00e4isen\u00e4 rutiinit,joilla sudokuetsin hakee satunnaisbitit: ensimm\u00e4inen palauttaa yhden merkin satunnaismerkin, ja jos sis\u00e4isen puskurin (gent) merkit loppuvat, hakee seuraavan puskurillisen pseudoressu_bytes() rutiinilla. Toinen rutiini palauttaa satunnaisen kokonaisluvun nollan ja halutun kokonaisluvun v\u00e4lill\u00e4. Funktion parametrin\u00e4 oleva yl\u00e4raja ei kuulu joukkoon, vaan maksimissaan palautetaan yht\u00e4 pienempi arvo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n    pseudoressu_bytes(sizeof(gent), gent);\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\nunsigned long newressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n  yl\u00e4rajak  } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n\n  return(word);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini palauttaa t\u00e4m\u00e4n sudokun (b) solun (cell) mahdolliset vaihtoehdot (choices2)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void sudoku_get_choices(unsigned char b&#91;82], int cell, char choices2&#91;10])\n{\n  int c, d, lin, col, box;\n  char choices&#91;10], digit&#91;2], digits&#91;]=\"123456789\";\n\n  lin = cell \/ 9;\n  col = cell % 9;\n  box = lin \/ 3 * 27 + col \/ 3 * 3;\n  \n  choices&#91;0] = '\\0';\n  \n  for(c = 0; c &lt; 9; c++) {\n    if(b&#91;lin * 9 + c] != ' ' &amp;&amp; strchr(choices, b&#91;lin * 9 + c]) == NULL) {\n      digit&#91;0] = b&#91;lin * 9 + c];\n      digit&#91;1] = '\\0';\n      strcat(choices, digit);\n    }\n  }\n  \n  for(c = 0; c &lt; 9; c++) {\n    if(b&#91;c * 9 + col] != ' ' &amp;&amp; strchr(choices, b&#91;c * 9 + col]) == NULL) {\n      digit&#91;0] = b&#91;c * 9 + col];\n      digit&#91;1] = '\\0';\n      strcat(choices, digit);\n    }\n  }\n  \n  for(c = 0; c &lt; 3; c++) {\n    for(d = 0; d &lt; 3; d++) {\n      if(b&#91;box + c * 9 + d] != ' ' &amp;&amp; strchr(choices, b&#91;box + c * 9 + d]) == NULL) {\n\tdigit&#91;0] = b&#91;box + c * 9 + d];\n\tdigit&#91;1] = '\\0';\n\tstrcat(choices, digit);\n      }\n    }\n  }\n  \n  choices2&#91;0] = '\\0';\n\n  for(c = 0; c &lt; 9; c++) {\n    if(strchr(choices, digits&#91;c]) == NULL) {\n      digit&#91;0] = digits&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(choices2, digit);\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraavilla sudoku_boardx() rutiineilla tulostetaan sudokuruudukot eri muodoissaan: seuraavana sudoku_board, joka tulostaa oletusmuotoilun mukaisen ruudukon (&#8211;board1).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void sudoku_board(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \"    A   B   C   D   E   F   G   H   I  \\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"|\\n\");\n    }\n    if(c % 27 == 0)\n      strcat(s,\"  +-----------+-----------+-----------+\\n\");\n    if(c % 9 == 0) {\n      sprintf(line,\"%c \",'A' + c \/ 9);\n      strcat(s, line);\n    }\n    if(c % 3 == 0) {\n      strcat(s, \"|\");\n    } else strcat(s, \" \");\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\" %c \", b&#91;c]);\n    else\n      sprintf(line,\"   \");\n    strcat(s, line);\n  }\n  strcat(s, \"|\\n  +-----------+-----------+-----------+\");\n  strcat(s, \"\\n\");\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavana sudoku ruudukon tulostava rutiini, joka tulostaa halutun muotoisen sudokun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void sudoku_print(unsigned char *b, int board)\n{\n  unsigned char string&#91;2048];\n\n  string&#91;0] = '\\0';\n  \n  \/* zero -&gt; no board *\/\n  if(board == 1) \n    sudoku_board(string, b);\n  else if(board == 2) \n    sudoku_board2(string, b);\n  else if(board == 3) \n    sudoku_board3(string, b);\n  else if(board == 4) \n    sudoku_board4(string, b);\n  else if(board == 5) \n    sudoku_board5(string, b);\n  else if(board == 6) \n    sudoku_board6(string, b);\n  else if(board == 10) \n    sudoku_board10(string, b);\n  else if(board == 11) \n    sudoku_board11(string, b);\n  else if(board == 20) \n    sudoku_board20(string, b);\n  else if(board == 21) \n    sudoku_board21(string, b);\n\n  fprintf(stdout,\"%s\", string);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa pienet rutiinit, joilla voidaan tarkastaa onko sudoku t\u00e4ynn\u00e4 (valmis), tai tyhjent\u00e4\u00e4 sudoku:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_full(unsigned char b&#91;82])\n{\n  for(int c = 0; c &lt; 81; c++) {\n    if(b&#91;c] == ' ')\n      return(0);\n  }\n  return(1);\n}\n\nvoid sudoku_clear(unsigned char b&#91;82])\n{\n  int c;\n  for(c = 0; c &lt; 81; c++) {\n    b&#91;c] = ' ';\n  }\n  b&#91;c] = '\\0';\n}<\/code><\/pre>\n\n\n\n<p>Seuraavaksi solve() rutiinin aliohjelma, jolla voidaan tarkastaa onko sudokuruudun (r) tietylle riville (i) ja tiettyyn sarakkeeseen (j) tietty numero mahdollinen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_isallowed(unsigned char b&#91;82], int i, int j, int e)\n{\n  int k, l, base;\n\n  for(k = 0; k &lt; 9; k++) {\n    if(b&#91;i * 9 + k] == e)\n      return(0);\n  }\n  for(k = 0; k &lt; 9; k++) {\n    if(b&#91;9 * k + j] == e)\n      return(0);\n  }\n  base = i \/ 3 * 27 + j \/ 3 * 3;\n  for(k = 0; k &lt; 3; k++) {\n    for(l = 0; l &lt; 3; l++) {\n      if(b&#91;base + k * 9 + l] == e)\n\treturn(0);\n    }\n  }\n  return(1);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavalla rutiinilla solve() hakee seuraavan solun, johon tarvitaan numero: eli palautetaan ensimm\u00e4isen tyhj\u00e4n ruudun rivi ja sarake.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_getnextemptycell(char *b, int *i, int *j)\n{\n  int i2, j2;\n  \n  for(i2 = 0; i2 &lt; 9; i2++) {\n    for(j2 = 0; j2 &lt; 9; j2++) {\n      if(*(b + i2 * 9 + j2) == ' ') {\n\t*i = i2;\n\t*j = j2;\n\treturn(1);\n      }\n    }\n  }\n  *i = -1;\n  *j = -1;\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa solve() rutiini. Solve2() on sen alirutiini, joka tekee varsinaisen rekursiivisen taulukon ratkaisun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_solve2(unsigned char *sudoku, unsigned char *solution, long long *solutions)\n{\n  int c, i, j;\n  \n  if(sudoku_getnextemptycell(sudoku, &amp;i, &amp;j) == 0) {\n    (*solutions)++;\n    if(solve_verbose) {\n      if(*solutions % 1000000000 == 0)\n\tfprintf(stdout,\"%lld: %s\\n\", *solutions, sudoku);\n    }\n    if(*solutions == 1)\n      strcpy(solution, sudoku);\n\n#ifdef SOLVE_QUICK_EXIT\n    if(solve_quick_exit &amp;&amp; *solutions &gt; 1) \/\/ quick exit &amp;&amp; multiple solutions, fail\n      return(1);\n    else\n#endif\n      return(0);\n  }\n\n  for(c = '1'; c &lt;= '9'; c++) {\n    if(sudoku_isallowed(sudoku, i, j, c) == 1) {\n#ifdef SOLVE_USESIMPLE\n      char savesudoku&#91;82];\n      if(solve_usesimple)\n\tstrcpy(savesudoku, sudoku);\n#endif\n      \n      *(sudoku + i * 9 + j) = c;\n      if(solve_verbose)\n\tfprintf(stdout,\"%s\\n\", sudoku);\n      \n#ifdef SOLVE_USESIMPLE\n      if(solve_usesimple)\n\tsudoku_simplesolve(sudoku);\n#endif\n      \n      solve_steps++;\n#ifdef DEBUG57\n      if(solve_verbose)\n\tfprintf(stdout,\"%s\\n\", sudoku);\n#endif\n      if(sudoku_solve2(sudoku, solution, solutions) == 1)\n\treturn(1);\n#ifdef SOLVE_USESIMPLE\n      if(solve_usesimple)\n\tstrcpy(sudoku, savesudoku);\n#endif\n      *(sudoku + i * 9 + j) = ' ';\n    }\n  }      \n  return(0);\n}\n\nint sudoku_solve(unsigned char *sudoku)\n{\n  unsigned char tsudoku&#91;82], solution&#91;82];\n\n  solve_steps = 0;\n  solutions = 0;\n  memcpy(tsudoku, sudoku, sizeof(tsudoku));\n  sudoku_simplesolve(tsudoku);\n  sudoku_solve2(tsudoku, solution, &amp;solutions);\n  if(solutions == 1) { \/\/ single solution\n    memcpy(sudoku, solution, sizeof(solution));\n    if(solve_verbose) {\n      fprintf(stdout,\"%s\\n\", sudoku);\n    }\n    return(1);\n  } else {\n    return(0);\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa simplesolven eri versiot: simplesolve1 ratkaisee tapaukset, joissa sudokuruudulla on vain yksi mahdollinen vaihtoehto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_simplesolve1(unsigned char b&#91;82])\n{\n  int c, changes = 0;\n  unsigned char choices&#91;10];\n\n  for(c = 0; c &lt; 81; c++) {\n    if(newb&#91;c] == ' ') { \/\/ empty cell\n      choices&#91;0] = '\\0';\n\n      sudoku_get_choices(newb, c, choices);\n\n      int lenchoices = strlen(choices);\n      if(lenchoices == 0) {\n\tbreak;\n      } else if(lenchoices == 1) {\n\tif(simple_verbose) {\n#ifdef DEBUG32\n\t  fprintf(stdout,\"simplesolve1\");\n#endif\n\t  fprintf(stdout,\" %c%c%c\", c \/ 9 + 'A', c % 9 + 'A', *choices);\n#ifdef DEBUG32\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n#endif\n\t}\n\tnewb&#91;c] = *choices;\n\tif(simple_verbose) {\n\t  simple_count++;\n\t  simple_output = 1;\n\t}\n#ifdef DEBUG32\n\tif(simple_verbose) {\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n\t}\n#endif\n\tchanges++;\n      } \/\/ end of if(strlen(choices)\n    } \/\/ end of if(b&#91;c] == ' ') { \/\/ empty cell\n  } \/\/ end of for(c\n\n  return(changes);\n}<\/code><\/pre>\n\n\n\n<p>Simplesolve2 ratkaisee tapaukset, joissa rivill\u00e4 numero sopii vain yhteen soluun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_simplesolve2(unsigned char b&#91;82]) {\n  int c, h, i, j, count, cell, base, changes = 0;\n  char choices&#91;81]&#91;10];\n  \n  for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n    for(i = 0; i &lt; 9; i++) { \/\/ rows\n      count = 0;\n      cell = -1;\n      for(j = 0; j &lt; 9; j++) { \/\/ columns\n\tif(newb&#91;i * 9 + j] == ' ' &amp;&amp; sudoku_isallowed(newb, i, j, c) == 1) {\n\t  count++;\n\t  cell = i * 9 + j;\n\t}\n      }\n      if(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\tif(simple_verbose) {\n#ifdef DEBUG34\n\t  fprintf(stdout,\"simplesolve2: rows\");\n#endif\n\t  fprintf(stdout,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n#ifdef DEBUG34\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n#endif\n\t}\n\tnewb&#91;cell] = c;\n\tif(simple_verbose) {\n\t  simple_count++;\n\t  simple_output = 1;\n\t}\n#ifdef DEBUG34\n\tif(simple_verbose) {\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n\t}\n#endif\n\tchanges++;\n\t\/\/sudoku_get_all_choices(b, choices);\n      }\n    }\n  }\n\n  return(changes);\n}<\/code><\/pre>\n\n\n\n<p>Simplesolve3 ratkaisee tapaukset, joissa sarakkeessa on vain yksi paikka, johon voi laittaa tietyn numeron:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_simplesolve3(unsigned char b&#91;82]) {\n  int c, h, i, j, count, cell, base, changes = 0;\n  char choices&#91;81]&#91;10];\n  \n  sudoku_get_all_choices(b, choices);\n\n  for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n    for(j = 0; j &lt; 9; j++) { \/\/ columns\n      count = 0;\n      cell = -1;\n      for(i = 0; i &lt; 9; i++) { \/\/ rows\n\tif(newb&#91;i * 9 + j] == ' ' &amp;&amp; sudoku_isallowed(newb, i, j, c) == 1) {\n\t  count++;\n\t  cell = i * 9 + j;\n\t}\n      }\n      if(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\tif(simple_verbose) {\n#ifdef DEBUG36\n\t  fprintf(stdout,\"simplesolve3: columns\");\n#endif\n\t  fprintf(stdout,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n\t  simple_output = 1;\n#ifdef DEBUG36\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n#endif\n\t}\n\tnewb&#91;cell] = c;\n\tsimple_count++;\n\n#ifdef DEBUG36\n\tif(simple_verbose) {\n\t  fprintf(stdout,\"\\n\");\n\t  sudoku_print(newb, 1);\n\t}\n#endif\n\tchanges++;\n\t\/\/sudoku_get_all_choices(b, choices);\n      }\n    }\n  }\n\n  return(changes);\n}\n<\/code><\/pre>\n\n\n\n<p>Simplesolve4 ratkaisee tapaukset joissa numero voidaan laittaa vain yhteen laatikon soluun:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int sudoku_simplesolve4(unsigned char b&#91;82]) {\n  int c, h, i, j, basei, basej, count, cell, changes = 0;\n  char choices&#91;81]&#91;10];\n  \n  for(basei = 0; basei &lt; 9; basei += 3) {\n    for(basej = 0; basej &lt; 9; basej += 3) {\n      for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n\tcount = 0;\n\tcell = -1;\n\tfor(i = 0; i &lt; 3; i++) {\n\t  for(j = 0; j &lt; 3; j++) {\n#ifdef KOK\n\t    fprintf(stdout,\"basei:%d\", basei);\n\t    fprintf(stdout,\" basej:%d\", basej);\n\t    fprintf(stdout,\" i:%d\", i);\n\t    fprintf(stdout,\" j:%d\", j);\n\t    fprintf(stdout,\" basei+i:%d\", basei + i);\n\t    fprintf(stdout,\" basej+j:%d\", basej + j);\n\t    fprintf(stdout,\" c:%d\", c);\n\t    fprintf(stdout,\" cell:%d\", cell);\n\t    fprintf(stdout,\"\\n\");\n#endif\n\t    if(newb&#91;(basei + i) * 9 + basej + j] == ' ' &amp;&amp; sudoku_isallowed(newb, basei + i, basej + j, c) == 1) {\n\t      cell = (basei + i) * 9 + j + basej;\n\t      count++;\n\t    }\n\t  }\n\t}\n\tif(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\t  if(simple_verbose) {\n#ifdef DEBUG38\n\t    fprintf(stdout,\"simplesolve4: boxes\");\n#endif\n\t    fprintf(stdout,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n#ifdef DEBUG38\n\t    fprintf(stdout,\"\\n\");\n\t    sudoku_print(newb, 1);\n#endif\n\t  }\n\t  newb&#91;cell] = c;\n\t  \n\t  if(simple_verbose) {\n\t    simple_count++;\n\t    simple_output = 1;\n\t  }\n#ifdef DEBUG38\n\t  if(simple_verbose) {\n\t    fprintf(stdout,\"\\n\");\n\t    sudoku_print(newb, 1);\n\t  }\n#endif\n\t  changes++;\n\t  \/\/sudoku_get_all_choices(b, choices);\n\t} \/\/ end of if(count\n      } \/\/ end of for(c\n    } \/\/ end of for(basej\n  } \/\/ end of for(basei\n\n  return(changes);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty ohjelmaan ensimm\u00e4inen kaavailu DB8 liittym\u00e4st\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>....\n#define aOUTPUTDB 2\n#define OUTPUTFILE 2\n\n#ifdef OUTPUTDB\n#include \"db8.h\"\n#endif\n....\n#ifdef OUTPUTDB\n\n  unsigned char temp&#91;16];\n  db8_set_filename(sudokuesdb);\n  db8_put_element(\"sudoku\", 0, \"board\", 0, b);\n  db8_put_element(\"sudoku\", 0, \"solution\", 0, s);\n  db8_put_element(\"sudoku\", 0, \"cboard\", 0, cboard);\n  sprintf(temp,\"%d\",digits);\n  db8_put_element(\"sudoku\", 0, \"digits\", 0, temp);\n  sprintf(temp,\"%d\",empty);\n  db8_put_element(\"sudoku\", 0, \"empty\", 0, temp);\n  if(gmode == 0) {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", 0, \"digitsa\", 0, temp);\n    sprintf(temp,\"%d\", digitsb);\n    db8_put_element(\"sudoku\", 0, \"digitsb\", 0, temp);\n  } else {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", 0, \"digitsa\", 0, temp);\n  }\n  sprintf(temp,\"%d\", mode);\n  db8_put_element(\"sudoku\", 0, \"mode\", 0, temp);\n  sprintf(temp,\"%d\", gmode);\n  db8_put_element(\"sudoku\", 0, \"gmode\", 0, temp);\n  db8_save(\"sudoku\");\n  db8_clear(\"sudoku\");\n#endif\n....<\/code><\/pre>\n\n\n\n<p>Ensimm\u00e4inen versio db8 koodista: aluksi koodin selostus ja sitten kokonainen koodi:<\/p>\n\n\n\n<p>Ensimm\u00e4inen rutiini parsii yhden nimi, arvo parin merkkijonosta p, len loppuisiin kenttiin laitetaan ko merkkijonon pituus: Ensimm\u00e4inen kappale parsii nimi-kent\u00e4n (name) ja toinen arvo kent\u00e4n (value). Rutiinin lopuksi kutsun p kentt\u00e4\u00e4n talletetaan merkkijonon &#8220;seuraava&#8221; kohta. Nimi kentt\u00e4 tunnistetaan yks\u00f6ishipsuista ja arvo lainausmerkeist\u00e4. Huomaa ettei kenttien lopussa ole &#8216;\\0&#8217; -merkki\u00e4 vaan merkkijonon p\u00e4\u00e4ttyminen pit\u00e4\u00e4 huomata len kentist\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_get_element2(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  *namelen = -1;\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *namelen = 0;\n    *name = p;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db8_skipwhite(&amp;p);\n\n  *valuelen = -1;\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *valuelen = 0;\n    *value = p;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG8\n  if(db8_verbose) {\n    fprintf(stderr,\"db8_get_element2():\");\n    fprintf(stderr,\" name:%.*s(%d)\", *namelen, *name, *namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", *valuelen, *value, *valuelen);\n    fprintf(stderr,\", next:%s\",p);\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n#endif\n  \n  *p2 = p;\n}<\/code><\/pre>\n\n\n\n<p>db8_get rutiini palauttaa halutun elementin tietueesta: set kertoo tietueen osoitteen, namelen kertoo name -kent\u00e4n pituuden, name -kent\u00e4ss\u00e4 on halutun kent\u00e4n nimi, valuesize kertoo arvolle varatun tilan, valuelen palauttaa sarakkeen arvon pituuden. rutiini palauttaa arvon value osoitteeseen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_get(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  if(*set == NULL)\n    return(0);\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n    \n  value&#91;0] = '\\0';\n\n  if(*set != NULL) {\n\n    firstelement = 1;\n    p = *set;\n    \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n            \n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}<\/code><\/pre>\n\n\n\n<p>db8_get_num() palauttaa j\u00e4rjestysnumerolla halutun kent\u00e4n nimen ja arvon: set kentt\u00e4 osoittaa tietueeseen, col m\u00e4\u00e4rittelee halutun kent\u00e4n j\u00e4rjestysnumeron, namesize kertoo kuinka paljon name kent\u00e4lle on varattu tilaa, namelen palauttaa nimen pituuden, name palauttaa nimen arvon, valuesize kertoo arvo -kent\u00e4lle varatun tilan, valuelen palauttaa arvon pituuden ja arvo palautetaan value kent\u00e4ss\u00e4.<\/p>\n\n\n\n<p>Rutiinissa tietue k\u00e4sitelll\u00e4\u00e4n kentt\u00e4 kent\u00e4lt\u00e4, j\u00e4rjestysnumeroa laskien. Kentt\u00e4, jonka j\u00e4rjestysnumero on yht\u00e4suuri kuin col parametriss\u00e4 annettu haluttu j\u00e4rjestysnumero palautetaan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_get_num(unsigned char **set, unsigned int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, col2, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  value&#91;0] = '\\0';\n\n  if(*set != NULL) {\n\n    firstelement = 1;\n    p = *set;\n    col2 = 0;\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n            \n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n\n      if(col2 == col &amp;&amp; name != NULL &amp;&amp; value != NULL) {\n\n\tstrncpy(name, name2, namesize);\n\tif(namesize &gt;= namelen2)\n\t  name&#91;namelen2] = '\\0';\n\telse\n\t  name&#91;namesize - 1] = '\\0';\n\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\n\tretval = 1;\n\tbreak;\n      }\n      col2++;\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}<\/code><\/pre>\n\n\n\n<p>Rutiini lis\u00e4\u00e4 halutun nimi, arvo parin tietueeseen: set kertoo osoitteen tietueeseen, namelen ja name kertovat nimi kent\u00e4n arvon ja valuelen, value kertovat arvo kent\u00e4n arvon:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_put(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n\n#ifdef DEBUG5\n  fprintf(stdout,\"\\ndb8_put: oldset:%s\", *set);\n  if(*set != NULL)\n    fprintf(stdout,\"(%ld)\", strlen(*set));\n\n  fprintf(stdout,\", namelen:%d\", namelen);\n  fprintf(stdout,\", name:%.*s\", namelen, name);\n  fprintf(stdout,\", valuelen:%d\", valuelen);\n  fprintf(stdout,\", value:%.*s\", valuelen, value);\n  fflush(stdout);\n#endif\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  firstelement = 1;\n  lastelement = 0;\n\n  if(*set != NULL &amp;&amp; strlen(*set) == 0) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set == NULL) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set != NULL) {\n\n    p = *set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      } else {\n\tif(*p == '\\0') {\n\t  lastelement = 1;\n\t  break;\n\t}\n      }\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } \/\/ end of if(set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n\n  if((firstelement &amp;&amp; found) || \/\/ first and existing\n     (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n    elementfmt = \"'%.*s' = \\\"%.*s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n  else if(firstelement) \/\/ first and not existing element\n    elementfmt = \"'%.*s' = \\\"%.*s\\\", \"; \/\/ --&gt; comma in the end (first new)\n  else\n    elementfmt = \", '%.*s' = \\\"%.*s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n\n  \/\/ print element\n\n  count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n  if(elementsize &lt; count) {\n    elementsize = count;\n    if((element = realloc(element, elementsize)) == NULL) {\n      fprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n    count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n  }\n\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(*set != NULL) {\n    count += strlen(*set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr, \"old length:%ld %s\\n\", oldcount, set);\n    fflush(stderr);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempset = *set;\n    if((*set = realloc(*set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = *set + (thiselement - tempset);\n    if(nextelement != NULL)\n      nextelement = *set + (nextelement - tempset);\n\n    if(tempset == NULL)\n      *set&#91;0] = '\\0';\n  }\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = *set + strlen(*set);\n  if(nextelement == NULL)\n    nextelement = *set + strlen(*set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr,\"new length:%ld %s\\n\", count, *set);\n    fflush(stderr);\n  }\n#endif  \n\n#ifdef DEBUG5\n  fprintf(stdout,\", newset:%s\\n\", *set);\n  fflush(stdout);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Rutiinilla valitaan &#8220;tietokannan&#8221; nimi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_set_filename(unsigned char *filename)\n{\n  FILE *fp1;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: set_filename\");\n    fprintf(stdout,\", filename=%s\", filename);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  if((fp1 = fopen(filename, \"r\"))==NULL) {\n    fprintf(stderr,\"%s: db8 cannot open file '%s'\\n\", procname, filename);\n    exit(1);\n  }\n  fclose(fp1);\n\n  strcpy(db8_filename, filename);\n\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_queryheader rutiinilla palautetaan osoite kyselyn otsakkeeseen. Jos kysely\u00e4 ei ollut olemassa, se luodaan. Jos kyselyotsake oli olemassa, se siirret\u00e4\u00e4n kyselyotsakelistan ensimm\u00e4iseksi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryheader *db8_queryheader(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *thisqh;\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh == NULL) { \/\/ create new\n    thisqh = malloc(sizeof(struct queryheader));\n    thisqh-&gt;queryname = malloc(strlen(queryname) + 1);\n    strcpy(thisqh-&gt;queryname, queryname);\n    thisqh-&gt;flags = 0;\n    thisqh-&gt;query = NULL;\n    thisqh-&gt;match = NULL;\n    thisqh-&gt;count = 0;\n    thisqh-&gt;preread = 20;\n    thisqh-&gt;next = firstqueryheader;\n    thisqh-&gt;first = NULL;\n    firstqueryheader = thisqh;\n  } else { \/\/ allready in list\n    \/\/ remove from list\n    thisqh = *ppqh;\n    *ppqh = thisqh-&gt;next;\n    \/\/ add back to 1st of list\n    thisqh-&gt;next = firstqueryheader;\n    firstqueryheader = thisqh;\n  }\n  return(thisqh);\n}<\/code><\/pre>\n\n\n\n<p>db_set_query() rutiinilla m\u00e4\u00e4ritell\u00e4\u00e4n kent\u00e4t, jotka halutaan: db8_query_header() palauttaa kyselyotsakkeen ja luo sen tarvittaessa. Kysely sijoitetaan kyselyotsakkeen query kentt\u00e4\u00e4n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_set_query(unsigned char *queryname, unsigned char *query)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_query\");\n  fprintf(stdout,\", query:%s\", query);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;query != NULL)\n    free(qh-&gt;query);\n\n  qh-&gt;query = malloc(strlen(query) + 1);\n  strcpy(qh-&gt;query, query);\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_set_match() rutiinilla rajataan rivit, joita kysely palauttaa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_set_match(unsigned char *queryname, unsigned char *match)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_match\");\n  fprintf(stdout,\", match:%s\", match);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;match != NULL)\n    free(qh-&gt;match);\n\n  qh-&gt;match = malloc(strlen(match) + 1);\n  strcpy(qh-&gt;match, match);\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_set_flags() rutiinilla m\u00e4\u00e4ritell\u00e4\u00e4n eri liput kyselylle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_set_queryflags(unsigned char *queryname, int flags)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_query\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", flags=%d\", flags);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n  qh-&gt;flags = flags;\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryline *db8_lineheader(unsigned char *queryname, int rownum)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n\n  add = 1;\n  qh = db8_queryheader(queryname);\n  ppql = &amp;qh-&gt;first;\n  while(*ppql != NULL) {\n    if(rownum == (*ppql)-&gt;rownum) { \/\/ matching row found\n      add = 0; \/\/ no need to add new\n      break;\n    } else if(rownum &lt; (*ppql)-&gt;rownum) { \/\/ first larger row\n      add = 1; \/\/ add new before\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n  if(add) {\n    struct queryline *thisql;\n    thisql = malloc(sizeof(struct queryline));\n    thisql-&gt;line = NULL;\n    thisql-&gt;rownum = rownum;\n    thisql-&gt;save = 0;\n    thisql-&gt;next = *ppql;\n    *ppql = thisql;\n  }\n  return(*ppql);\n}\n<\/code><\/pre>\n\n\n\n<p>db8_match() vertaa tietuetta match merkkijonoon, ja palauttaa ykk\u00f6sen, jos ne matsaavat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_match: match:%s\", match);\n    fprintf(stdout,\", set:%s\", set);\n    fflush(stdout);\n  }\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db8_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db8_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;m); \/\/ match\n    db8_skipwhite(&amp;m);\n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb8_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s); \/\/ set\n      db8_skipwhite(&amp;s);\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n#ifdef DEBUG5\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>db8_free_set() rutiini vapauttaa muistialueen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_free_set(unsigned char **set)\n{\n  if(*set != NULL) {\n    free(*set);\n    *set = NULL;\n  }\n}<\/code><\/pre>\n\n\n\n<p>db8_project() ker\u00e4\u00e4 kyselyn query kent\u00e4t set tietueesta ja kirjoittaa ne project kentt\u00e4\u00e4n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_project(unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8_project: \");\n  fprintf(stdout,\", query:%s\", query);\n  fprintf(stdout,\", set:%s\\n\", set);\n  fflush(stdout); fflush(stdout);\n#endif\n\n#ifdef DEBUG52\n  fprintf(stdout,\"db8_project: \");\n  fprintf(stdout,\", set:%s\\n\", set);\n#endif\n  \n  if(*project != NULL)\n    *(project&#91;0]) = '\\0';\n  \n  q = query;\n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db8_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb8_skipwhite(&amp;s);\n      }\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n#ifdef DEBUG52\n\tfprintf(stdout,\"db8_project: \");\n\tfprintf(stdout,\", '%.*s'\", namelen, name);\n\tfprintf(stdout,\" = \\\"%.*s\\\"\", valuelen2, value2);\n\tfprintf(stdout,\"\\n\");\n#endif\n\tdb8_put(project, namelen, name, valuelen2, value2);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n#ifdef DEBUG5\n  fprintf(stdout,\", project:(%s)\", *project);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>db8_fgets() lukee merkkijonon tiedostosta, ja lis\u00e4\u00e4 tarvittaessa palautettavan muistialueen kokoa: stringlen osoittaa t\u00e4m\u00e4n hetkiseen muistialueen kokoon ja string osoittaa puskuriin, johon merkkijono kirjoitetaan. fp1 on tiedoston k\u00e4sittelyosoite. Sek\u00e4 palalautettavan muistialueen koko ja muistialue palautetaan kutsujalle.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *db8_fgets(int *stringlen, unsigned char **string, FILE *fp1)\n{\n  int count, retval, done;\n  unsigned char buffer&#91;128];\n  unsigned char *buf = *string;\n\n  count = 0;\n\n  if(buf != NULL)\n    buf&#91;0] = '\\0';\n\n  retval = 1;\n  done = 0;\n\n  for(;;) {\n    if(fgets(buffer, sizeof(buffer), fp1) == NULL) {\n      retval = 0;\n      break;\n    }\n    \n    if(buffer&#91;strlen(buffer)-1] == '\\n') {\n      buffer&#91;strlen(buffer)-1] = '\\0';\n      done = 1;\n    }\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: buffer: %s\\n\", buffer);\n#endif\n    count = 0;\n    if(buf != NULL)\n      count += strlen(buf);\n    count += strlen(buffer) + 1;\n    \n    if(*stringlen &lt; count) {\n      unsigned char *prevbuf = buf;\n      *stringlen = count;\n      buf = realloc(buf, *stringlen);\n      if(prevbuf == NULL)\n\tbuf&#91;0] = '\\0';\n    }\n    \n    strcat(buf, buffer);\n\n    if(done)\n      break;\n  }\n  *string = buf;\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: string: %s\\n\", *string);\n#endif\n  \n#ifdef DEBUG63\n  fprintf(stdout,\"%s\\n\", *string);\n#endif\n  \n  if(retval == 0)\n    return(NULL);\n  else {\n    return(*string);\n  }\n}<\/code><\/pre>\n\n\n\n<p>db8_get_element() lukee tietyn kent\u00e4n kyselyn rivilt\u00e4. Kyselyn nimi on queryname kent\u00e4ss\u00e4. Rivinumero kerrotaan rownum kent\u00e4ss\u00e4, kent\u00e4n nimi kerrotaan namelen ja name kentiss\u00e4, palautettava arvo tulee valuesize, valuelen ja value kenttiin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n \n  FILE *fp1;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      \/\/if(buffer&#91;strlen(buffer) - 1] == '\\n')\n      \/\/  buffer&#91;strlen(buffer) - 1] = '\\0';\n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_free_set(&amp;project);\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  fprintf(stdout,\"\\n====row:%s\", row);\n\t  match = 1;\n\t}\n      }\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;qline-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_get_element_num() lukee  kent\u00e4n rivilt\u00e4 sarakenumerolla. Rivin numero on rownum kent\u00e4ss\u00e4, sarakkeen numero on col kent\u00e4ss\u00e4. Sarakkeen nimi palautetaan namesize, namelen, name kentiss\u00e4 ja sarakkeen arvo palautetaan valuesize, valuelen ja value kentiss\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n  FILE *fp1;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  fflush(stdout);\n\t  match = 1;\n\t}\n      }\n      \/\/fprintf(stdout,\"match:%d\\n\",match);\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element_num:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n      }\n      rownum2++;\n    }\n    fclose(fp1);\n  }\n  \n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;qline-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>db_put_element() kirjoittaa sarakkeen nimen ja arvon kyselyn riville. Sarake kirjoitetaan riville jonka j\u00e4rjestysnumero annetaan kent\u00e4ss\u00e4 rownum. Kirjoitettava nimi annetaan namelen ja name kentiss\u00e4, ja arvo annetaan valuelen ja value kentiss\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_put_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: put_element\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", namelen=%u\", namelen);\n    fprintf(stdout,\", name=%.*s\", namelen, name);\n    fprintf(stdout,\", valuelen=%u\", valuelen);\n    fprintf(stdout,\", value=%.*s\", valuelen, value);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  \/\/db8_set = db8_find_set(queryname, rownum);\n\n  ql = db8_lineheader(queryname, rownum);\n  db8_put(&amp;ql-&gt;line, namelen, name, valuelen, value); \/\/ 2023 JariK\n  ql-&gt;save = 1;\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_save() kirjoittaa muutetut tietueet lokitiedoston loppuun (t\u00e4ss\u00e4 ~tietokanta)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_save(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save:\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  qh = db8_queryheader(queryname);\n\n  fprintf(stdout,\"%s\\n\",db8_set);\n\n  FILE *fp1;\n  if((fp1 = fopen(db8_filename, \"a\"))==NULL) {\n    fprintf(stdout,\"%s: db8 cannot open file '%s'\\n\", procname, db8_filename);\n    exit(1);\n  }\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(ql-&gt;save) {\n      fprintf(fp1,\"%s\\n\", ql-&gt;line);\n      ql-&gt;save = 0;\n    }\n    ql = ql-&gt;next;\n  }\n  \n  fclose(fp1);\n\n  db8_dump(queryname);\n\n  return(0);\n}\n<\/code><\/pre>\n\n\n\n<p>db8_save_all() kirjoittaa kaikkien kyselyiden (query) kaikki tehdyt muutokset tietokantaan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_save_all()\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    db8_save(qh-&gt;queryname);\n    qh = qh-&gt;next;\n  }\n  return(0);\n}\n<\/code><\/pre>\n\n\n\n<p>db8_clear() vapauttaa tietyn kyselyn allokoimat tietoalueet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_clear(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *qh;\n  struct queryline *ql, *qlnext;\n  \n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"clear %s\", queryname);\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh != NULL) {\n    qh = *ppqh;\n    ql = qh-&gt;first;\n    *ppqh = qh-&gt;next;\n    free(qh);\n    \n    while(ql != NULL) {\n      qlnext = ql-&gt;next;\n      if(ql-&gt;line != NULL)\n\tfree(ql-&gt;line);\n      free(ql);\n      ql = qlnext;\n    }\n  }\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_clear_all() vapauttaa kaikkien kyselyiden kaikki tietoalueet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_clear_all()\n{\n  struct queryheader *qh, *qhnext;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_clear_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    qhnext = qh-&gt;next;\n    db8_clear(qh-&gt;queryname);\n    qh = qhnext;\n  }\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_exit() lopettaa tietokantahallinnan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_exit()\n{\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_exit:\\n\");\n  }\n#endif\n  \n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>sig_handler() rutiinilla ohjelma vastaanottaa ctrl-c painallukset. Jos ctrl-c:t\u00e4 painetaan ctrlcquit muuttujaan talletetaan yksi. Pidemm\u00e4n luupin aikana voidaan katsoa ctrlcquitin arvoa ja lopettaa luuppi tarvittaessa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int ctrlcquit = 0;\n\nstatic void sig_handler()\n{\n  fprintf(stderr,\"Ctrl-c pressed\\n\");\n  ctrlcquit = 1;\n  \/\/signal(SIGINT, SIG_DFL);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavalla saadaan selville onko merkki nimeen sopiva merkki. Merkiksi kelpaavat alfanumeeriset merkit (isalpha() ja isdigit()), utf8-merkit (&gt;=80) ja alaviiva.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int db8_ischar(int c)\n{\n  if(isalpha(c) || isdigit(c) || c &gt;= 0x80 || c == '_')\n    return(1);\n  else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_isquote:lla saadaan selville, onko merkki &#8220;lainausmerkiksi&#8221; sopiva merkki. Lainausmerkeiksi kelpaavat kaikki v\u00e4limerkit (ispunct()) paitsi pilkku (kenttien v\u00e4lill\u00e4 oleva merkki) ja yht\u00e4suuruus (nimen ja arvon v\u00e4liss\u00e4 oleva merkki).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_isquote(int c)\n{\n  if(ispunct(c) &amp;&amp; c != ',' &amp;&amp; c != '=')\n    return(1);\n  else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_get_element3() parsii nimi arvo parin siten ett\u00e4 t\u00e4ss\u00e4 versiossa voi k\u00e4ytt\u00e4\u00e4 haluamaansa lainausmerkki\u00e4 (katso isquite()).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int namequote = -1, valuequote = -1;\n\nstatic void db8_get_element3(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  if(namequote == -1) {\n    if(db8_isquote(*p))\n      namequote = *p;\n    else\n      namequote = 0;\n  }\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 1 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *namelen = -1;\n  if((*p == namequote &amp;&amp; namequote) ||\n     (db8_ischar(*p) &amp;&amp; !namequote)) { \/\/ name\n    *namelen = 0;\n#ifdef DEBUG60\n    fprintf(stdout,\"db8_get_element: 2 %s\\n\", p);\n#endif\n    if(namequote) {\n      p++;\n      *name = p;\n      while(*p != namequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 3 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n      if(*p == namequote)\n\tp++;\n    } else {\n      *name = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 4 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n    }\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n    db8_skipwhite(&amp;p);\n  }\n\n  if(valuequote == -1) {\n    if(db8_isquote(*p))\n      valuequote = *p;\n    else\n      valuequote = 0;\n  }\n  \n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 5 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *valuelen = -1;\n  if((*p == valuequote &amp;&amp; valuequote) ||\n     (db8_ischar(*p) &amp;&amp; !valuequote)) { \/\/ value\n    *valuelen = 0;\n    if(valuequote) {\n      p++;\n#ifdef DEBUG60\n      fprintf(stdout,\"db8_get_element: 6 %s\\n\", p);\n#endif\n      *value = p;\n      while(*p != valuequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 7 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n      if(*p == valuequote)\n\tp++;\n    } else {\n      *value = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 8 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n    }\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 9 %s\\n\", p);\n#endif\n  *p2 = p;\n}<\/code><\/pre>\n\n\n\n<p>db8_squery() parsii ja suorittaa yhden kyselyn: Ensimm\u00e4isess\u00e4 kappaleessa parsitaan komento l\u00e4pi ja muodostetaan kysely oikeilla v\u00e4limerkeill\u00e4. Seuraavassa kappaleessa suoritetaan kysely ja tulostetaan vastaus rivi rivilt\u00e4, sarake sarakkeelta.<\/p>\n\n\n\n<p>Toisen kappaleen aikana tarkkaillaan my\u00f6s control c:n painalluksia(ctrlcquit) ja more toiminnon quitteja (morequit)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_squery(unsigned char *query) \/\/ JariK 2025 single\n{\n  int row, col, first, ok, print;\n\n  unsigned int namelen;\n  unsigned int valuelen;\n  unsigned char *name, *value;\n\n  unsigned char *q;\n  unsigned char *query2 = NULL;\n\n  if(more)\n    more_init(); \/\/ adjust thee screensize\n  \n  q = query;\n  fprintf(stdout,\"query:%s\\n\", query);\n  fflush(stdout);\n\n  namequote = -1;\n  valuequote = -1;  \n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element3(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    if(name == NULL)\n      break;\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n    fprintf(stderr,\"db8_squery():\");\n    fprintf(stderr,\" name:%.*s(%d)\", namelen, name, namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", valuelen, value, valuelen);\n    fprintf(stderr,\"\\n\");\n    db8_put(&amp;query2, namelen, name, valuelen, value);\n  }\n  db8_set_filename(db8_filename);\n  fprintf(stdout,\"query2:%s\\n\", query2);\n  db8_clear(\"query\");\n  db8_set_query(\"query\", query2);\n  free(query2);\n  row = 0;\n\n  unsigned int namesize2, namelen2, valuesize2, valuelen2;\n  unsigned char name2&#91;128], value2&#91;128];\n\n  namesize2 = sizeof(name2);\n  valuesize2 = sizeof(value2);\n\n  for(;;) {\n\n    morequit = 0;\n    print = 0;\n    first = 1;\n    col = 0;\n    ok = 0;\n    for(;;) {\n      \/\/fprintf(stdout,\"row:%d, col:%d, \", row, col);\n      \n      if(db8_get_element_num(\"query\", row, col, namesize2, &amp;namelen2, name2, valuesize2, &amp;valuelen2, value2))\n\tok = 1;\n      else\n\tbreak;\n\n      if(col == 0)\n\tfprintf(stdout,\"%d \", row);\n      \n      if(!first)\n\tfprintf(stdout,\", \");\n\n      print = 1;\n      \n      more_printf(stdout,\"'%s' = \\\"%s\\\"\", name2, value2);\n      fflush(stdout);\n      col++;\n      first = 0;\n    }\n    if(print) {\n      more_printf(stdout,\"\\n\");\n      fflush(stdout);\n    }\n    \n    if(!ok)\n      break;\n    if(more &amp;&amp; morequit)\n      break;\n    if(ctrlcquit) {\n      ctrlcquit = 0;\n      break;\n    }\n    row++;\n }\n  \/\/db8_dump(\"query\");\n}<\/code><\/pre>\n\n\n\n<p>db8_isword() tarkistaa komennon yhden sanan. Jos sana m\u00e4ts\u00e4\u00e4, ohitetaan sana komennosta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int db8_isword(unsigned char **p2, unsigned char *word)\n{\n  unsigned char *p;\n\n  p = *p2;\n  db8_skipwhite(&amp;p);\n  if(!strncmp(word, p, strlen(word))) {\n    p += strlen(word);\n    db8_skipwhite(&amp;p);\n    *p2 = p;\n    return(1);\n  } else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>db8_iquery() toteuttaa kyselyjen interaktiivisen tekemisen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char prompt&#91;128] = \"skk&gt;\";\n\nvoid db8_iquery() \/\/ JariK 2025 interactive\n{\n  unsigned char *command = NULL, *p;\n  int commandsize = 0;\n\n  ctrlcquit = 0;\n  signal(SIGINT, sig_handler);\n  fprintf(stdout,\"%s\\n\", programname);\n  \n  for(;;) {\n    fprintf(stdout, \"%s\", prompt);\n    db8_fgets(&amp;commandsize, &amp;command, stdin);\n    p = command;\n    db8_skipwhite(&amp;p);\n    if(*p == '\\0')\n       continue;\n    if(db8_isword(&amp;p, \"more\")) {\n      if(db8_isword(&amp;p, \"on\")) {\n\tmore = 1;\n\tcontinue;\n      }\n      if(db8_isword(&amp;p, \"off\")) {\n\tmore = 0;\n\tcontinue;\n      }\n      more = !more;\n      fprintf(stderr,\"more \");\n      if(more)\n\tfprintf(stderr,\"on\");\n      else\n\tfprintf(stderr,\"off\");\n      fprintf(stderr,\"\\n\");\n      continue;\n    }\n    if(db8_isword(&amp;p, \"exit\"))\n      break;\n    if(db8_isword(&amp;p, \"quit\"))\n      break;\n    db8_squery(p);\n  }\n  signal(SIGINT, SIG_DFL);\n}<\/code><\/pre>\n\n\n\n<p>Ohjelman voi k\u00e4\u00e4nt\u00e4\u00e4 db8 ohjelmaksi, joka koostuu db8.c:st\u00e4 ja more.c:st\u00e4, jolloin seuraava MAIN lohko sis\u00e4lt\u00e4\u00e4 p\u00e4\u00e4ohjelman:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef MAIN\n\nunsigned char *procname;\n\nint iquery = 0;\nchar *query = NULL;\nunsigned char filename&#91;128] = \"newressusudoku.skk.db\";\n\nint main(int argc, char *argv&#91;])\n{\n  int c, args = 0, help = 0;\n  \n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n    \n    if(!strcmp(\"--help\", argv&#91;c])) {\n      help = 1;\n\n    } else if(!strcmp(\"--args\", argv&#91;c])) {\n      args = !args;\n\n    } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t      !strcmp(\"--version\", argv&#91;c])) {\n      fprintf(stderr, \"%s\", programname);\n      fprintf(stderr, \", %s\\n\", copyright);\n      exit(0);\n      \n    } else if(!strncmp(\"--skkfile\", argv&#91;c], 9)) { \/\/ JariK 2025\n      if(*(argv&#91;c] + 9) != '\\0') {\n\tstrcpy(filename, argv&#91;c] + 9);\n      } else if(c + 1 &lt; argc) {\n\tstrcpy(filename, argv&#91;c + 1]);\n\tc++;\n      }\n    } else if(!strncmp(\"--query\", argv&#91;c], 7)) { \/\/ JariK 2025\n      query = NULL;\n      if(*(argv&#91;c] + 7) != '\\0') {\n\tquery = argv&#91;c] + 7;\n      } else if(c + 1 &lt; argc &amp;&amp; *(argv&#91;c + 1]) != '-') {\n\tquery = argv&#91;c + 1];\n\tc++;\n      }\n      \n    } else if(!strncmp(\"--more\", argv&#91;c], 6)) { \/\/ JariK 2025\n      more = !more;\n    }\n  }\n\n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--skkfile&#91;filename]]\");\n    fprintf(stderr,\" &#91;--query&#91;querytext]]\");\n    fprintf(stderr,\" &#91;--more]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  if(args) {\n    fprintf(stderr,\"argc: %d\\n\", argc);\n    for(c = 0; c &lt; argc; c++) {\n      fprintf(stderr,\"argv&#91;%d]: %s\\n\", c, argv&#91;c]);\n    }\n    exit(1);\n  }\n  \n  db8_set_filename(filename);\n  \n  if(query !=NULL)\n    db8_squery(query);\n  else\n    db8_iquery();\n\n  exit(0);\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>Seuraavassa n\u00e4yte db8:n ajosta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.03 \u00a9\nskk&gt;'steps', 'rounds', 'digits'\nquery:'steps', 'rounds', 'digits'\ndb8_squery(): name:steps(5), value:(null)(-1)\ndb8_squery(): name:rounds(6), value:(null)(-1)\ndb8_squery(): name:digits(6), value:(null)(-1)\nquery2:'steps', 'rounds', 'digits'\n0 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n1 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n2 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n3 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n4 'steps' = \"0\", 'rounds' = \"3\", 'digits' = \"27\"\n5 'steps' = \"0\", 'rounds' = \"6\", 'digits' = \"27\"\n6 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"28\"\n7 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"29\"\n8 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n9 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n10 'steps' = \"0\", 'rounds' = \"5\", 'digits' = \"27\"\n11 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n12 'steps' = \"0\", 'rounds' = \"5\", 'digits' = \"27\"\n13 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\n14 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"25\"\n15 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"29\"\n16 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"25\"\n17 'steps' = \"10\", 'rounds' = \"0\", 'digits' = \"27\"\n18 'steps' = \"10\", 'rounds' = \"0\", 'digits' = \"25\"\n19 'steps' = \"10\", 'rounds' = \"0\", 'digits' = \"29\"\n20 'steps' = \"10\", 'rounds' = \"0\", 'digits' = \"26\"\n21 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"25\"\n22 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"30\"\n23 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"25\"\n24 'steps' = \"9\", 'rounds' = \"0\", 'digits' = \"28\"\n25 'steps' = \"0\", 'rounds' = \"4\", 'digits' = \"27\"\nskk&gt;exit\n$ \n<\/code><\/pre>\n\n\n\n<p>Lista n\u00e4ytt\u00e4\u00e4 muuten hyv\u00e4lt\u00e4, mutta esimerkiksi nelj\u00e4 ensimm\u00e4ist\u00e4 rivi\u00e4 ovat samanlaisia, eli tarvittaisiin valinnainen distinct toiminto. Toinen ongelma on se, ett\u00e4 rivej\u00e4 ei ole lajiteltu oikein. Tein jo aikanaan n\u00e4m\u00e4 toiminnot aiemmin terttuutil1:een t\u00e4ss\u00e4 raportissa.<\/p>\n\n\n\n<p>Distinct ja sort tulisivat get_element ja get_element_num funktioihin. Seuraavassa alkuper\u00e4iset rutiinit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n \n  FILE *fp1;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      \/\/if(buffer&#91;strlen(buffer) - 1] == '\\n')\n      \/\/  buffer&#91;strlen(buffer) - 1] = '\\0';\n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_free_set(&amp;project);\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  fprintf(stdout,\"\\n====row:%s\", row);\n\t  match = 1;\n\t}\n      }\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;qline-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n  FILE *fp1;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  match = 1;\n\t}\n      }\n      \/\/fprintf(stdout,\"match:%d\\n\",match);\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element_num:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  \n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;qline-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>Kirjoitellaan n\u00e4m\u00e4 rutiinit uudestaan samojen p\u00e4tkien vuoksi: Toisaalta t\u00e4ss\u00e4 on ehk\u00e4 liikaa toimintoja yhdess\u00e4 funktiossa. Seuraavassa samat rivit jaettuna nelj\u00e4\u00e4n funktiot, samat rivit eri j\u00e4rjestyksess\u00e4. Rivit on jaettu eri funktioihin toiminnan perusteella ja p\u00e4\u00e4llimm\u00e4inen funktio kutsuu toimintoja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG65 2\n\nstatic int db8_matchandproject(unsigned char *queryname, unsigned char *row)\n{\n  struct queryheader *qh;\n  int match;\n  unsigned char *project = NULL;\n  \n  qh = db8_queryheader(queryname);\n  match = 0;\n  if(qh-&gt;match == NULL ||\n     strstr(row, qh-&gt;match) != NULL)\n    match = 1;\n  if(match) {\n    match = 0;\n    if(qh-&gt;query == NULL)\n      match = 1;\n    else if(db8_match(row, qh-&gt;query)) {\n      db8_free_set(&amp;project);\n      db8_project(&amp;project, row, qh-&gt;query);\n      strcpy(row, project);\n      match = 1;\n    }\n  }\n  return(match);\n}\n\nstruct queryline *db8_get_line(unsigned char *queryname, int rownum)\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2, count;\n  \n  FILE *fp1;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n      if(db8_matchandproject(queryname, row)) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG65\n\t  fprintf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 ||\n\t     count &gt; rownum + qh-&gt;preread)\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  return(qline);\n}\n\n#define aDEBUG64 2\n#define aDEBUG68 2\n#define aDEBUG69 2\n\nint db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  ql = db8_get_line(queryname, rownum);\n\n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;ql-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  ql = db8_get_line(queryname, rownum);\n  \/\/fprintf(stdout,\"ql:%s\\n\",ql-&gt;line);\n  \n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;ql-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavissa rutiineissa lis\u00e4tty DB8_ROWSORT ja DB8_DISTINCT kytkimet kyselyyn. get_line() funktio on samankaltainen kun ennenkin. Sit\u00e4 on muutettu siten, ett\u00e4 aluksi levylt\u00e4luku lukee koko tiedoston ja muodostaa kyselyn mukaiset tiedot. Sen j\u00e4lkeen tiedostoa ei lueta en\u00e4\u00e4, tiedon pit\u00e4isi olla kokonaan kasassa. Ensimm\u00e4isen kappaleen j\u00e4lkeen on iffi (if(ql == NULL&#8230;)) joka est\u00e4\u00e4 uudelleenluvut. Toisessa kappaleessa on (if(flags&#8230;)) iffi, joka valitsee oikean version v\u00e4limuistiin talletuksesta. Toisessa kappaleessa on toinen iffi ((if flags) continue), joka pit\u00e4\u00e4 huolen ett\u00e4 koko tiedosto selataan kerralla kokonaan. Funktion lopussa on uudelleen numerointi (db8_renumber()) ja tietueiden laskenta (db8_countsets()).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> struct queryline *db8_get_line(unsigned char *queryname, int rownum)\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2, count;\n  \n  FILE *fp1;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n\n  if(ql == NULL &amp;&amp; qh-&gt;flags &amp;&amp; qh-&gt;count != 0)\n    return(NULL);\n\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n      if(db8_matchandproject(queryname, row)) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  if(qh-&gt;flags) {\n\t    ql = db8_cacheset_flags(queryname, rownum2, row);\n\t  } else {\n\t    ql = db8_cache_set(queryname, rownum2, row);\n\t  }\n#ifdef DEBUG65\n\t  more_printf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\t  if(qh-&gt;flags) \/\/ sorting --&gt; read all\n\t    continue;\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 ||\n\t     count &gt; rownum + qh-&gt;preread)\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n\n    fclose(fp1);\n\n    if(qh-&gt;flags) {\n      db8_renumbersets(queryname);\n      db8_countsets(queryname);\n      qline = qh-&gt;first;\n    }\n  }\n    \n  return(qline);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava funktio on alkuper\u00e4inen kyselyn v\u00e4limuistiin talletus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryline *db8_cache_set(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  struct queryline *ql;\n  \n#ifdef DEBUG59\n  fprintf(stdout,\"db8_cache_set:\");\n  fprintf(stdout,\" %d\", rownum);\n  fprintf(stdout,\" %s\", set);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  ql = db8_lineheader(queryname, rownum);\n  if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n    exit(1);\n  }\n  strcpy(ql-&gt;line, set);\n\n  return(ql);\n}\n<\/code><\/pre>\n\n\n\n<p>Erikoisversio v\u00e4limuistin talletuksesta, jossa huolehditaan ett\u00e4 rivit ovat ainutlaatuisia (distinct) ja\/tai lajiteltu (sort):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryline *db8_cacheset_flags(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n  \n  qh = db8_queryheader(queryname);\n\n  add = 1;\n\n  ppql = &amp;qh-&gt;first;\n\n  while(*ppql != NULL) {\n    if((qh-&gt;flags &amp; DB8_DISTINCT) &amp;&amp;\n       !strcmp(set, (*ppql)-&gt;line) ) {\n      add = 0;\n      break;\n    }\n    if((qh-&gt;flags &amp; DB8_ROWSORT) &amp;&amp;\n       strcmp(set, (*ppql)-&gt;line) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n\n  if(add) {\n    struct queryline *ql;\n    ql = malloc(sizeof(struct queryline));\n    if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n      fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n      exit(1);\n    }\n    strcpy(ql-&gt;line, set);\n#ifdef DEBUG61\n    more_printf(stdout,\"db8_cacheset_flags:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    ql-&gt;rownum = 0;\n    ql-&gt;next = *ppql;\n    *ppql = ql;\n  }\n  \n  return(NULL);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini uudelleennumeroi rivit (levyhaun j\u00e4lkeen):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_renumbersets(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rownum;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rownum = 0;\n  while(ql != NULL) {\n    ql-&gt;rownum = rownum;\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_renumbersets:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rownum++;\n    ql = ql-&gt;next;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Seuraavalla lasketaan haun j\u00e4lkeen kuinka paljon rivej\u00e4 on:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void db8_countsets(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rows;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rows = 0;\n  while(ql != NULL) {\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_countsets:\");\n    more_printf(stdout,\" %d:\", rows);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rows++;\n    ql = ql-&gt;next;\n  }\n  qh-&gt;count = rows;\n  more_printf(stdout,\"%d rows\\n\", rows);\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavasta ajosta n\u00e4kyy, ett\u00e4 lajittelu on sinnep\u00e4in mutta numeeristen tietojen lajittelussa p\u00e4\u00e4dyt\u00e4\u00e4n v\u00e4\u00e4r\u00e4\u00e4n j\u00e4rjestykseen: (sataset ovat v\u00e4\u00e4r\u00e4ss\u00e4 paikassa) Samoin distinct n\u00e4ytt\u00e4\u00e4 toimivan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.03 \u00a9\nskk&gt;guesses\nquery:guesses\ndb8_squery(): name:guesses(7), value:(null)(-1)\nquery2:'guesses'\n15 rows\n0 'guesses' = \"0\"\n1 'guesses' = \"110\"\n2 'guesses' = \"113\"\n3 'guesses' = \"128\"\n4 'guesses' = \"27\"\n5 'guesses' = \"28\"\n6 'guesses' = \"33\"\n7 'guesses' = \"35\"\n8 'guesses' = \"37\"\n9 'guesses' = \"39\"\n10 'guesses' = \"40\"\n11 'guesses' = \"56\"\n12 'guesses' = \"64\"\n13 'guesses' = \"66\"\n14 'guesses' = \"68\"\nskk&gt;<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 uusi &#8220;numeroviisas&#8221; lajittelurutiini db8_strcmp_num():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static long db8_strcmp_num(unsigned char *p, unsigned char *q)\n{\n  unsigned long num1, num2;\n\n  for(;;) {\n    \/\/fprintf(stdout,\"p:%s, q:%s\\n\", p, q);\n    if(isdigit(*p) &amp;&amp; isdigit(*q)) {\n      num1 = db8_atol(&amp;p);\n      num2 = db8_atol(&amp;q);\n      if(num1 - num2 != 0)\n\treturn(num1 - num2);\n    } else if(*p - *q != 0) {\n      return(*p - *q);\n    } else {\n      if(*p == '\\0' || *q == '\\0')\n\tbreak;\n      p++;\n      q++;\n    }\n  }\n  return(0);\n}\"<\/code><\/pre>\n\n\n\n<p>Ja lajittelurutiiniin kokonaisluvun parsiminen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned long db8_atol(unsigned char **p)\n{\n  int count;\n  unsigned long num;\n\n  count = 0;\n  num = 0;\n  while(isdigit(**p) &amp;&amp; count++ &lt; 19) { \/\/ calculate 19 first digits\n    num = num * 10 + (**p - '0');\n    \/\/more_printf(stdout,\"%ld\\n\", num);\n    (*p)++;\n  }\n  while(isdigit(**p)) { \/\/ skip rest\n    (*p)++;\n  }\n  return(num);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa uusi ajo: jossa sataset ovat kohdallaan.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.03 \u00a9\nskk&gt;guesses\nquery:guesses\ndb8_squery(): name:guesses(7), value:(null)(-1)\nquery2:'guesses'\n15 rows\n0 'guesses' = \"0\"\n1 'guesses' = \"27\"\n2 'guesses' = \"28\"\n3 'guesses' = \"33\"\n4 'guesses' = \"35\"\n5 'guesses' = \"37\"\n6 'guesses' = \"39\"\n7 'guesses' = \"40\"\n8 'guesses' = \"56\"\n9 'guesses' = \"64\"\n10 'guesses' = \"66\"\n11 'guesses' = \"68\"\n12 'guesses' = \"110\"\n13 'guesses' = \"113\"\n14 'guesses' = \"128\"\nskk&gt;<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 paikka jossa edellist\u00e4 uutta lajittelurutiinia k\u00e4ytet\u00e4\u00e4n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct queryline *db8_cacheset_flags(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n  \n  qh = db8_queryheader(queryname);\n\n  add = 1;\n\n  ppql = &amp;qh-&gt;first;\n\n  while(*ppql != NULL) {\n    if((qh-&gt;flags &amp; DB8_DISTINCT) &amp;&amp;\n       !strcmp(set, (*ppql)-&gt;line) ) {\n      add = 0;\n      break;\n    }\n    if((qh-&gt;flags &amp; DB8_ROWSORT) &amp;&amp;\n       db8_strcmp_num(set, (*ppql)-&gt;line) &lt; 0) {\n      \/\/strcmp(set, (*ppql)-&gt;line) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n\n  if(add) {\n    struct queryline *ql;\n    ql = malloc(sizeof(struct queryline));\n    if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n      fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n      exit(1);\n    }\n    strcpy(ql-&gt;line, set);\n#ifdef DEBUG61\n    more_printf(stdout,\"db8_cacheset_flags:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    ql-&gt;rownum = 0;\n    ql-&gt;next = *ppql;\n    *ppql = ql;\n  }\n  \n  return(NULL);\n}\n<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty sudokuid sudokuriville: t\u00e4m\u00e4 on v\u00e4h\u00e4n t\u00e4mm\u00f6inen karvalakkimalli mutta ensimm\u00e4isen\u00e4 versiona ihan mukiinmenev\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef OUTPUTDB\n\n  unsigned char temp&#91;16];\n  int templen = 0, itemp = 0;\n  static long nextsudokuid = -1;\n  \n  db8_set_filename(sudokuesdb);\n  db8_set_query(\"nextsudokuid\", \"'sudokuid'\");\n\n  nextsudokuid = 0;\n  for(int c = 0;; c++) {\n    if(db8_get_element(\"nextsudokuid\", c, 0, \"sudokuid\", sizeof(temp), &amp;templen, temp)) {\n    } else break;\n    itemp = atol(temp);\n    if(nextsudokuid &lt; itemp)\n      nextsudokuid = itemp;\n  }\n  nextsudokuid++;\n  db8_clear(\"nextsudokuid\");\n  fprintf(stdout,\"nextsudouid:%ld\\n\", nextsudokuid);\n\n  static int row = 0;\n  \n  db8_set_filename(sudokuesdb);\n  sprintf(temp,\"%ld\", nextsudokuid);\n  nextsudokuid++;\n  db8_put_element(\"sudoku\", row, 0, \"sudokuid\", 0, temp);\n  db8_put_element(\"sudoku\", row, 0, \"board\", 0, b);\n  db8_put_element(\"sudoku\", row, 0, \"solution\", 0, s);\n  db8_put_element(\"sudoku\", row, 0, \"cboard\", 0, cboard);\n  sprintf(temp,\"%d\",digits);\n  db8_put_element(\"sudoku\", row, 0, \"digits\", 0, temp);\n  sprintf(temp,\"%d\",empty);\n  db8_put_element(\"sudoku\", row, 0, \"empty\", 0, temp);\n  if(gmode == 0) {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n    sprintf(temp,\"%d\", digitsb);\n    db8_put_element(\"sudoku\", row, 0, \"digitsb\", 0, temp);\n  } else {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n  }\n  sprintf(temp,\"%d\", mode);\n  db8_put_element(\"sudoku\", row, 0, \"mode\", 0, temp);\n  sprintf(temp,\"%d\", gmode);\n  db8_put_element(\"sudoku\", row, 0, \"gmode\", 0, temp);\n  sprintf(temp,\"%d\", save_guesses);\n  db8_put_element(\"sudoku\", row, 0, \"guesses\", 0, temp);\n  sprintf(temp,\"%d\", save_steps);\n  db8_put_element(\"sudoku\", row, 0, \"steps\", 0, temp);\n  sprintf(temp,\"%d\", save_rounds);\n  db8_put_element(\"sudoku\", row, 0, \"rounds\", 0, temp);\n  db8_save(\"sudoku\");\n  db8_clear(\"sudoku\");\n\n  row++;\n  \n#endif<\/code><\/pre>\n\n\n\n<p>Edellinen toimii hyvin yhden k\u00e4ytt\u00e4j\u00e4n ohjelmassa, mutta jos asiakasprosesseja on enemm\u00e4n tarvitaan lukituksia: t\u00e4ss\u00e4 lukituksiin k\u00e4ytet\u00e4\u00e4n semaphoreja. sem_open() avaa semaforin, sem_wait() odottaa semaforia(), sem_post() vapauttaa semaforin. sem_close() sulkee semaforin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define USE_SEMAPHORES 2\n\n#ifdef USE_SEMAPHORES\n\nstatic sem_t *mutex;\nstatic char *semname = \"sudokusemaphore\";\n\n#define DEBUG17 2\n\nvoid my_sem_open()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_open()\\n\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_unlink()\\n\");\n#endif\n  if(sem_unlink(semname) == 0) {\n    fprintf(stdout, \"%s: previous semaphore %s removed\\n\", procname, semname);\n  }\n  \n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_open()\\n\");\n#endif\n  if((mutex = sem_open(semname, O_CREAT, 0644, 1)) == SEM_FAILED) {\n    \/\/if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {\n    fprintf(stderr, \"\\n%s: cannot sem_open()\", procname);\n    fprintf(stderr,\" errno %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr, \"\\n\");\n    perror(\"sem_open\");\n  }\n}\n\nvoid my_sem_wait()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_wait()\\n\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_wait()\\n\");\n#endif\n  if(sem_wait(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_wait()\", procname);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_wait\");\n  }\n}\n\nvoid my_sem_post()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_post()\\n\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_post()\\n\");\n#endif\n  if(sem_post(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_post()\", procname);\n    fprintf(stderr, \", errno: %d\\n\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    perror(\"sem_post\");\n  }\n}\n\nvoid my_sem_close()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_close()\\n\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_unlink()\\n\");\n#endif\n  sem_unlink(semname);\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_close()\\n\");\n#endif\n  sem_close(mutex);\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>Seuraavassa sudokutietueen kirjoitus semaphoreilla: alussa sem_wait() ja lopussa sem_post().<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef OUTPUTDB\n\n  unsigned char temp&#91;16];\n  int templen = 0, itemp = 0;\n  static long nextsudokuid = -1;\n\n#ifdef USE_SEMAPHORES\n  my_sem_wait();\n#endif\n  \n  db8_set_filename(sudokuesdb);\n  db8_set_query(\"nextsudokuid\", \"'sudokuid'\");\n\n  nextsudokuid = 0;\n  for(int c = 0;; c++) {\n    if(db8_get_element(\"nextsudokuid\", c, 0, \"sudokuid\", sizeof(temp), &amp;templen, temp)) {\n    } else break;\n    itemp = atol(temp);\n    if(nextsudokuid &lt; itemp)\n      nextsudokuid = itemp;\n  }\n  nextsudokuid++;\n  db8_clear(\"nextsudokuid\");\n  fprintf(stdout,\"nextsudouid:%ld\\n\",nextsudokuid);\n\n  static int row = 0;\n  \n  db8_set_filename(sudokuesdb);\n  sprintf(temp,\"%ld\", nextsudokuid);\n  nextsudokuid++;\n  db8_put_element(\"sudoku\", row, 0, \"sudokuid\", 0, temp);\n  db8_put_element(\"sudoku\", row, 0, \"board\", 0, b);\n  db8_put_element(\"sudoku\", row, 0, \"solution\", 0, s);\n  db8_put_element(\"sudoku\", row, 0, \"cboard\", 0, cboard);\n  sprintf(temp,\"%d\",digits);\n  db8_put_element(\"sudoku\", row, 0, \"digits\", 0, temp);\n  sprintf(temp,\"%d\",empty);\n  db8_put_element(\"sudoku\", row, 0, \"empty\", 0, temp);\n  if(gmode == 0) {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n    sprintf(temp,\"%d\", digitsb);\n    db8_put_element(\"sudoku\", row, 0, \"digitsb\", 0, temp);\n  } else {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n  }\n  sprintf(temp,\"%d\", mode);\n  db8_put_element(\"sudoku\", row, 0, \"mode\", 0, temp);\n  sprintf(temp,\"%d\", gmode);\n  db8_put_element(\"sudoku\", row, 0, \"gmode\", 0, temp);\n  sprintf(temp,\"%d\", save_guesses);\n  db8_put_element(\"sudoku\", row, 0, \"guesses\", 0, temp);\n  sprintf(temp,\"%d\", save_steps);\n  db8_put_element(\"sudoku\", row, 0, \"steps\", 0, temp);\n  sprintf(temp,\"%d\", save_rounds);\n  db8_put_element(\"sudoku\", row, 0, \"rounds\", 0, temp);\n  db8_save(\"sudoku\");\n  db8_clear(\"sudoku\");\n\n  row++;\n\n#ifdef USE_SEMAPHORES\n  my_sem_post();\n#endif\n  \n#endif<\/code><\/pre>\n\n\n\n<p>Nyt voidaan hakea sudokuid:ll\u00e4 tietty sudoku:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/db8\nDB8 version 0.04 \u00a9\nskk&gt;sudokuid = 1, board\nquery:sudokuid = 1, board\ndb8_squery(): name:sudokuid(8), value:1(1)\ndb8_squery(): name:board(5), value:(null)(-1)\nquery2:'sudokuid' = \"1\", 'board'\n1 rows\n0 'sudokuid' = \"1\", 'board' = \"61 9 82       27      4 61    16   8  78  4    4  73     7     3  4  1 55   9 8  \"\nskk&gt;<\/code><\/pre>\n\n\n\n<p>Seuraavassa koko db8.c ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n\n#include \"db8.h\"\n#include \"more.h\"\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"DB8 version 0.04 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n\/\/#define MAIN 2 \/\/ in makefile\n\/\/#define QUERY 2 \/\/ in makefile\n\nint db8_verbose = 0;\n\nunsigned char *db8_set = NULL;\n\nvoid db8_skipwhite(unsigned char **p)\n{\n  while(isblank(**p))\n    (*p)++;\n}\n\n#define aDEBUG8 2\n#define aDEBUG9 2\n#define aDEBUG10 2\n#define aDEBUG11 2\n\nvoid db8_get_element2(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  *namelen = -1;\n  if(*p == '\\'') { \/\/ name\n    p++;\n    *namelen = 0;\n    *name = p;\n    while(*p != '\\'' &amp;&amp; *p != '\\0') {\n      p++;\n      (*namelen)++;\n    }\n    if(*p == '\\'')\n      p++;\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n  }\n\n  db8_skipwhite(&amp;p);\n\n  *valuelen = -1;\n  if(*p == '\\\"') { \/\/ value\n    p++;\n    *valuelen = 0;\n    *value = p;\n    while(*p != '\\\"' &amp;&amp; *p != '\\0') {\n      p++;\n      (*valuelen)++;\n    }\n    if(*p == '\\\"')\n      p++;\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG8\n  if(db8_verbose) {\n    fprintf(stderr,\"db8_get_element2():\");\n    fprintf(stderr,\" name:%.*s(%d)\", *namelen, *name, *namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", *valuelen, *value, *valuelen);\n    fprintf(stderr,\", next:%s\",p);\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n#endif\n  \n  *p2 = p;\n}\n\n#define aDEBUG5 2\n\nint db8_get(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  if(*set == NULL)\n    return(0);\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n    \n  value&#91;0] = '\\0';\n\n  if(*set != NULL) {\n\n    firstelement = 1;\n    p = *set;\n    \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n            \n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) {\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\tretval = strlen(value);\n\tbreak;\n      }\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}\n\nint db8_get_num(unsigned char **set, unsigned int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int firstelement, col2, retval = 0;\n  unsigned char *p;\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  value&#91;0] = '\\0';\n  \n  if(*set != NULL) {\n    firstelement = 1;\n    p = *set;\n    col2 = 0;\n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      }\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n\n      if(col2 == col &amp;&amp; name != NULL &amp;&amp; value != NULL) {\n\n\tstrncpy(name, name2, namesize);\n\tif(namesize &gt;= namelen2)\n\t  name&#91;namelen2] = '\\0';\n\telse\n\t  name&#91;namesize - 1] = '\\0';\n\n\tstrncpy(value, value2, valuesize);\n\tif(valuesize &gt;= valuelen2)\n\t  value&#91;valuelen2] = '\\0';\n\telse\n\t  value&#91;valuesize - 1] = '\\0';\n\n\tretval = 1;\n\tbreak;\n      }\n      col2++;\n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n  } \/\/ end of if(set != NULL)\n  return(retval);\n}\n\n#define aSORTED 2\n#define aDEBUG17 2\n\nvoid db8_put(unsigned char **set, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value) \/\/ 2023 JariK\n{\n  int found = 0, firstelement, lastelement;\n  unsigned char *p, *currentelement = NULL;\n  unsigned char *thiselement = NULL, *nextelement = NULL;\n\n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n\n#ifdef DEBUG5\n  fprintf(stdout,\"\\ndb8_put: oldset:%s\", *set);\n  if(*set != NULL)\n    fprintf(stdout,\"(%ld)\", strlen(*set));\n\n  fprintf(stdout,\", namelen:%d\", namelen);\n  fprintf(stdout,\", name:%.*s\", namelen, name);\n  fprintf(stdout,\", valuelen:%d\", valuelen);\n  fprintf(stdout,\", value:%.*s\", valuelen, value);\n  fflush(stdout);\n#endif\n\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n  firstelement = 1;\n  lastelement = 0;\n\n  if(*set != NULL &amp;&amp; strlen(*set) == 0) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set == NULL) {\n    lastelement = 1;\n    firstelement = 1;\n  } else if(*set != NULL) {\n\n    p = *set;\n \n    \/\/ read thru elements element by element\n    \n    while(*p != '\\0') {\n\n      db8_skipwhite(&amp;p);\n      \n      currentelement = p; \/\/ save beginning of element\n\n      if(!firstelement) {\n\tif(*p == ',')\n\t  p++;\n\tdb8_skipwhite(&amp;p);\n      } else {\n\tif(*p == '\\0') {\n\t  lastelement = 1;\n\t  break;\n\t}\n      }\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;p);\n\n      db8_skipwhite(&amp;p);\n      \n      \/\/ we reached equal name\n      \n      if(namelen == namelen2 &amp;&amp;\n\t !strncmp(name, name2, namelen) ) {\n\tfound = 1;\n\tthiselement = currentelement;\n\tnextelement = p; \/\/ beginning of next element\n\tbreak;\n      }\n\n#ifdef SORTED\n\n      \/\/ we reached greater name\n\n      if(namelen == namelen2 &amp;&amp;\n\t strncmp(name, name2, namelen) &lt; 0) { \/\/ equal lengths less (aaaa, bbbb)\n\tthiselement = currentelement;\n\tnextelement = currentelement;\n\tbreak;\n\n      } else {\n\n\t\/\/ common beginning of strings\n\t\n\tint comblen = namelen;\n\tif(comblen &gt; namelen2)\n\t  comblen = namelen2;\n\t\n\tint cmp = strncmp(name, name2, comblen);\n\tif((cmp &lt; 0) || \/\/ first characters less (aaaa, b)\n\t   (!cmp &amp;&amp; namelen2 &gt; namelen) ) { \/\/ first characters equal but string longer (a, aaaa)\n\t  thiselement = currentelement;\n\t  nextelement = currentelement;\n\t  break;\n\t}\n      }\n    \n#endif\n      \n      if(*p == '\\0')\n\tlastelement = 1;\n  \n      firstelement = 0;\n    } \/\/ end of while(*p != '\\0')\n\n  } \/\/ end of if(set != NULL)\n\n  \/\/ make new element\n\n  long count;\n  static long elementsize = 0;\n  static unsigned char *element = NULL;\n  unsigned char *elementfmt;\n\n  \/\/ figure out needed commas\n  if(value != NULL) {\n    if((firstelement &amp;&amp; found) || \/\/ first and existing\n       (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n      elementfmt = \"'%.*s' = \\\"%.*s\\\"\"; \/\/ --&gt; no commas (first existing or only)\n    else if(firstelement) \/\/ first and not existing element\n      elementfmt = \"'%.*s' = \\\"%.*s\\\", \"; \/\/ --&gt; comma in the end (first new)\n    else\n      elementfmt = \", '%.*s' = \\\"%.*s\\\"\"; \/\/ ..&gt; comma in the beginning (other)\n  \n    count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n    if(elementsize &lt; count) {\n      elementsize = count;\n      if((element = realloc(element, elementsize)) == NULL) {\n\tfprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n\texit(1);\n      }\n      count = snprintf(element, elementsize, elementfmt, namelen, name, valuelen, value) + 1;\n    }\n  } else { \/\/ else of if(value != NULL\n\n    if((firstelement &amp;&amp; found) || \/\/ first and existing\n       (firstelement &amp;&amp; lastelement) ) \/\/ first element in a new set (first and last)\n      elementfmt = \"'%.*s'\"; \/\/ --&gt; no commas (first existing or only)\n    else if(firstelement) \/\/ first and not existing element\n      elementfmt = \"'%.*s', \"; \/\/ --&gt; comma in the end (first new)\n    else\n      elementfmt = \", '%.*s'\"; \/\/ ..&gt; comma in the beginning (other)\n  \n    count = snprintf(element, elementsize, elementfmt, namelen, name) + 1;\n    if(elementsize &lt; count) {\n      elementsize = count;\n      if((element = realloc(element, elementsize)) == NULL) {\n\tfprintf(stderr, \"%s: realloc(): cannot allocate memory\\n\", procname);\n\texit(1);\n      }\n      count = snprintf(element, elementsize, elementfmt, namelen, name) + 1;\n    } \/\/ end of if(elementsize &lt; count\n  } \/\/ end of if(value != NULL\n\n  \/\/ calculate change in length\n\n  long oldcount = 0;\n  \n  count = 0;\n  if(*set != NULL) {\n    count += strlen(*set);\n    oldcount = count + 1; \/\/ + '\\0'\n  }\n  if(found) \/\/ change in value only\n    count += valuelen - valuelen2; \/\/ no punctuation marks\n  else\n    count += strlen(element);\n  count++; \/\/ + '\\0'\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr, \"old length:%ld %s\\n\", oldcount, set);\n    fflush(stderr);\n  }\n#endif  \n\n  if(oldcount != count) { \/\/ size changed, \n\n    \/\/ reallocate set according to new length\n\n    unsigned char *tempset = *set;\n    if((*set = realloc(*set, count)) == NULL) {\n      fprintf(stderr,\"%s: realloc(): cannot allocate memory\\n\", procname);\n      exit(1);\n    }\n\n    \/\/ adjust these too\n    \n    if(thiselement != NULL)\n      thiselement = *set + (thiselement - tempset);\n    if(nextelement != NULL)\n      nextelement = *set + (nextelement - tempset);\n\n    if(tempset == NULL)\n      *set&#91;0] = '\\0';\n  }\n  \n  \/\/ adjust to end of set if not present\n  \n  if(thiselement == NULL)\n    thiselement = *set + strlen(*set);\n  if(nextelement == NULL)\n    nextelement = *set + strlen(*set);\n\n  \/\/ move end of the set\n\n  memmove(thiselement + strlen(element), nextelement, strlen(nextelement) + 1); \/\/ end of string too\n\n  \/\/ add new element\n  \n  memmove(thiselement, element, strlen(element));\n\n#ifdef DEBUG11\n  if(oldcount != count) {\n    fprintf(stderr,\"new length:%ld %s\\n\", count, *set);\n    fflush(stderr);\n  }\n#endif  \n\n#ifdef DEBUG5\n  fprintf(stdout,\", newset:%s\\n\", *set);\n  fflush(stdout);\n#endif\n}\n\nunsigned char db8_filename&#91;128];\n\nint db8_set_filename(unsigned char *filename)\n{\n  FILE *fp1;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: set_filename\");\n    fprintf(stdout,\", filename=%s\", filename);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  if((fp1 = fopen(filename, \"r\"))==NULL) {\n    fprintf(stderr,\"%s: db8 cannot open file '%s'\\n\", procname, filename);\n    exit(1);\n  }\n  fclose(fp1);\n\n  strcpy(db8_filename, filename);\n\n  return(0);\n}\n\nstruct queryheader *firstqueryheader = NULL;\n\nstruct queryheader *db8_queryheader(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *thisqh;\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh == NULL) { \/\/ create new\n    thisqh = malloc(sizeof(struct queryheader));\n    thisqh-&gt;queryname = malloc(strlen(queryname) + 1);\n    strcpy(thisqh-&gt;queryname, queryname);\n    thisqh-&gt;flags = 0;\n    thisqh-&gt;query = NULL;\n    thisqh-&gt;match = NULL;\n    thisqh-&gt;count = 0;\n    thisqh-&gt;preread = 20;\n    thisqh-&gt;next = firstqueryheader;\n    thisqh-&gt;first = NULL;\n    firstqueryheader = thisqh;\n  } else { \/\/ allready in list\n    \/\/ remove from list\n    thisqh = *ppqh;\n    *ppqh = thisqh-&gt;next;\n    \/\/ add back to 1st of list\n    thisqh-&gt;next = firstqueryheader;\n    firstqueryheader = thisqh;\n  }\n  return(thisqh);\n}\n\nint db8_set_query(unsigned char *queryname, unsigned char *query)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_query\");\n  fprintf(stdout,\", query:%s\", query);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;query != NULL)\n    free(qh-&gt;query);\n\n  qh-&gt;query = malloc(strlen(query) + 1);\n  strcpy(qh-&gt;query, query);\n  \n  return(0);\n}\n\n#define aDEBUG42 2\n\nint db8_set_match(unsigned char *queryname, unsigned char *match)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_match\");\n  fprintf(stdout,\", match:%s\", match);\n  fprintf(stdout,\"\\n\");\n#endif\n#ifdef DEBUG42\n  fprintf(stdout,\"db8: set_match\");\n  fprintf(stdout,\", match:%s\", match);\n  fprintf(stdout,\"\\n\");\n#endif\n    \n  qh = db8_queryheader(queryname);\n\n  if(qh-&gt;match != NULL)\n    free(qh-&gt;match);\n\n  qh-&gt;match = malloc(strlen(match) + 1);\n  strcpy(qh-&gt;match, match);\n  \n  return(0);\n}\n\nint db8_get_queryflags(unsigned char *queryname)\n{\n  struct queryheader *qh;\n\n  qh = db8_queryheader(queryname);\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: get_queryflags\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", flags=%d\", qh-&gt;flags);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  \n  return(qh-&gt;flags);\n}\n\nint db8_set_queryflags(unsigned char *queryname, int flags)\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8: set_queryflags\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", flags=%d\", flags);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n  qh-&gt;flags = flags;\n  \n  return(0);\n}\n\nstruct queryline *db8_lineheader(unsigned char *queryname, int rownum)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n\n  add = 1;\n  qh = db8_queryheader(queryname);\n  ppql = &amp;qh-&gt;first;\n  while(*ppql != NULL) {\n    if(rownum == (*ppql)-&gt;rownum) { \/\/ matching row found\n      add = 0; \/\/ no need to add new\n      break;\n    } else if(rownum &lt; (*ppql)-&gt;rownum) { \/\/ first larger row\n      add = 1; \/\/ add new before\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n  if(add) {\n    struct queryline *thisql;\n    thisql = malloc(sizeof(struct queryline));\n    thisql-&gt;line = NULL;\n    thisql-&gt;rownum = rownum;\n    thisql-&gt;save = 0;\n    thisql-&gt;next = *ppql;\n    *ppql = thisql;\n  }\n  return(*ppql);\n}\n\n#define aDEBUG48 2\n\nint db8_match(unsigned char *set, unsigned char *match)\n{\n  int ok, ok2, first1, first2;\n  \n  unsigned char *s, *m;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_match: match:%s\", match);\n    fprintf(stdout,\", set:%s\", set);\n    fflush(stdout);\n  }\n#endif\n  \n#ifdef DEBUG48\n  fprintf(stdout,\"db8_match: match:%s\", match);\n  fprintf(stdout,\", set:%s\", set);\n  fflush(stdout);\n#endif\n  \n  m = match;\n  first2 = 1;\n  ok = 1;\n  while(*m != '\\0') {\n    db8_skipwhite(&amp;m);\n    if(!first2) {\n      if(*m == ',')\n\tm++;\n      db8_skipwhite(&amp;m);\n    }\n    first2 = 0;\n    \n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;m); \/\/ match\n    db8_skipwhite(&amp;m);\n\n    s = set;\n    first1 = 1;\n    ok2 = 0;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      if(!first1) {\n\tif(*s == ',')\n\t  s++;\n\tdb8_skipwhite(&amp;s);\n      }\n      first1 = 0;\n\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s); \/\/ set\n      db8_skipwhite(&amp;s);\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n\tok2 = 1;\n\tbreak;\n      }\n    }\n    if(ok2 == 0)\n      ok = 0;\n  }\n\n#ifdef DEBUG48\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n#ifdef DEBUG5\n  fprintf(stdout,\", ok:%d\", ok);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n\n  return(ok);\n}\n\nvoid db8_free_set(unsigned char **set)\n{\n  if(*set != NULL) {\n    free(*set);\n    *set = NULL;\n  }\n}\n\n#define aDEBUG52 2\n\nvoid db8_project(unsigned char **project, unsigned char *set, unsigned char *query)\n{\n  unsigned char *q, *s;\n\n  unsigned int namelen, valuelen;\n  unsigned char *name, *value;\n  unsigned int namelen2, valuelen2;\n  unsigned char *name2, *value2;\n\n#ifdef DEBUG5\n  fprintf(stdout,\"db8_project: \");\n  fprintf(stdout,\", query:%s\", query);\n  fprintf(stdout,\", set:%s\\n\", set);\n  fflush(stdout); fflush(stdout);\n#endif\n\n#ifdef DEBUG52\n  fprintf(stdout,\"db8_project: \");\n  fprintf(stdout,\" set:%s\\n\", set);\n#endif\n  \n  if(*project != NULL)\n    *(project&#91;0]) = '\\0';\n  \n  q = query;\n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element2(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n\n    s = set;\n    while(*s != '\\0') {\n      db8_skipwhite(&amp;s);\n      db8_get_element2(&amp;namelen2, &amp;name2, &amp;valuelen2, &amp;value2, &amp;s);\n      db8_skipwhite(&amp;s);\n      if(*s == ',') {\n\ts++;\n\tdb8_skipwhite(&amp;s);\n      }\n\n      if((name != NULL &amp;&amp; namelen == namelen2 &amp;&amp; !strncmp(name, name2, namelen)) &amp;&amp;\n\t (value == NULL || (valuelen == valuelen2 &amp;&amp; !strncmp(value, value2, valuelen))) ) {\n#ifdef DEBUG52\n\tfprintf(stdout,\"db8_project: \");\n\tfprintf(stdout,\"'%.*s'\", namelen, name);\n\tfprintf(stdout,\" = \\\"%.*s\\\"\", valuelen2, value2);\n\tfprintf(stdout,\"\\n\");\n#endif\n\tdb8_put(project, namelen, name, valuelen2, value2);\n\t\n      }\n    } \/\/ while(*s != '\\0'\n  } \/\/ while(*q != '\\0'\n#ifdef DEBUG5\n  fprintf(stdout,\", project:(%s)\", *project);\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n}\n\n#define aDEBUG63 2\n#define aDEBUG54 2\n\nunsigned char *db8_fgets(int *stringlen, unsigned char **string, FILE *fp1)\n{\n  int count, retval, done;\n  unsigned char buffer&#91;128];\n  unsigned char *buf = *string;\n\n  count = 0;\n\n  if(buf != NULL)\n    buf&#91;0] = '\\0';\n\n  retval = 1;\n  done = 0;\n\n  for(;;) {\n    if(fgets(buffer, sizeof(buffer), fp1) == NULL) {\n      retval = 0;\n      break;\n    }\n    \n    if(buffer&#91;strlen(buffer)-1] == '\\n') {\n      buffer&#91;strlen(buffer)-1] = '\\0';\n      done = 1;\n    }\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: buffer: %s\\n\", buffer);\n#endif\n    count = 0;\n    if(buf != NULL)\n      count += strlen(buf);\n    count += strlen(buffer) + 1;\n    \n    if(*stringlen &lt; count) {\n      unsigned char *prevbuf = buf;\n      *stringlen = count;\n      buf = realloc(buf, *stringlen);\n      if(prevbuf == NULL)\n\tbuf&#91;0] = '\\0';\n    }\n    \n    strcat(buf, buffer);\n\n    if(done)\n      break;\n  }\n  *string = buf;\n\n#ifdef DEBUG54\n    fprintf(stdout,\"db8_fgets: string: %s\\n\", *string);\n#endif\n  \n#ifdef DEBUG63\n  fprintf(stdout,\"%s\\n\", *string);\n#endif\n  \n  if(retval == 0)\n    return(NULL);\n  else {\n    return(*string);\n  }\n}\n\n#ifdef OLD1\n\n#define aDEBUG64 2\n#define aDEBUG68 2\n#define aDEBUG69 2\n\nint db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n \n  FILE *fp1;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      \/\/if(buffer&#91;strlen(buffer) - 1] == '\\n')\n      \/\/  buffer&#91;strlen(buffer) - 1] = '\\0';\n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_free_set(&amp;project);\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  fprintf(stdout,\"\\n====row:%s\", row);\n\t  match = 1;\n\t}\n      }\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;qline-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  int rownum2, count, match;\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  static unsigned char *project = NULL;\n  FILE *fp1;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n\n#ifdef DEBUG68\n      fprintf(stdout,\"&gt;%s\\n\", row);\n#endif\n  \n      match = 0;\n      if(qh-&gt;match == NULL ||\n\t strstr(row, qh-&gt;match) != NULL)\n\tmatch = 1;\n      if(match) {\n\tmatch = 0;\n\tif(qh-&gt;query == NULL)\n\t  match = 1;\n\telse if(db8_match(row, qh-&gt;query)) {\n\t  db8_project(&amp;project, row, qh-&gt;query);\n\t  strcpy(row, project);\n\t  match = 1;\n\t}\n      }\n      \/\/fprintf(stdout,\"match:%d\\n\",match);\n      if(match) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  ql = db8_lineheader(queryname, rownum2);\n\t  if((ql-&gt;line = malloc(strlen(row) + 1)) == NULL) {\n\t    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n\t    exit(1);\n\t  }\n\t  strcpy(ql-&gt;line, row);\n#ifdef DEBUG68\n\t  fprintf(stdout,\"=%s\\n\", row);\n#endif\n#ifdef DEBUG64\n\t  fprintf(stdout,\"db8_get_element_num:\");\n\t  fprintf(stdout,\" rownum:%u\", rownum2);\n\t  fprintf(stdout,\" row:%s\", ql-&gt;line);\n\t  fprintf(stdout,\"\\n\");\n#endif\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 || \/\/ no preread\n\t     count &gt; rownum + qh-&gt;preread) \/\/ preread enough\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n    fclose(fp1);\n  }\n  \n  if(qline != NULL &amp;&amp; qline-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", qline-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;qline-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}\n\n#endif\n\n#define aDEBUG65 2\n\nstatic int db8_matchandproject(unsigned char *queryname, unsigned char *row)\n{\n  struct queryheader *qh;\n  int match;\n  unsigned char *project = NULL;\n  \n  qh = db8_queryheader(queryname);\n  match = 0;\n  if(qh-&gt;match == NULL ||\n     strstr(row, qh-&gt;match) != NULL)\n    match = 1;\n  if(match) {\n    match = 0;\n    if(qh-&gt;query == NULL)\n      match = 1;\n    else if(db8_match(row, qh-&gt;query)) {\n      db8_free_set(&amp;project);\n      db8_project(&amp;project, row, qh-&gt;query);\n      strcpy(row, project);\n      match = 1;\n    }\n  }\n  return(match);\n}\n\nstatic unsigned long db8_atol(unsigned char **p)\n{\n  int count;\n  unsigned long num;\n\n  count = 0;\n  num = 0;\n  while(isdigit(**p) &amp;&amp; count++ &lt; 19) { \/\/ calculate 19 first digits\n    num = num * 10 + (**p - '0');\n    \/\/more_printf(stdout,\"%ld\\n\", num);\n    (*p)++;\n  }\n  while(isdigit(**p)) { \/\/ skip rest\n    (*p)++;\n  }\n  return(num);\n}\n\nstatic long db8_strcmp_num(unsigned char *p, unsigned char *q)\n{\n  unsigned long num1, num2;\n\n  for(;;) {\n    \/\/fprintf(stdout,\"p:%s, q:%s\\n\", p, q);\n    if(isdigit(*p) &amp;&amp; isdigit(*q)) {\n      num1 = db8_atol(&amp;p);\n      num2 = db8_atol(&amp;q);\n      if(num1 - num2 != 0)\n\treturn(num1 - num2);\n    } else if(*p - *q != 0) {\n      return(*p - *q);\n    } else {\n      if(*p == '\\0' || *q == '\\0')\n\tbreak;\n      p++;\n      q++;\n    }\n  }\n  return(0);\n}\n\n#define aDEBUG61\n\n#define aDEBUG59 2\n\nstruct queryline *db8_cache_set(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  struct queryline *ql;\n  \n#ifdef DEBUG59\n  fprintf(stdout,\"db8_cache_set:\");\n  fprintf(stdout,\" %d\", rownum);\n  fprintf(stdout,\" %s\", set);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  ql = db8_lineheader(queryname, rownum);\n  if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n    fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n    exit(1);\n  }\n  strcpy(ql-&gt;line, set);\n\n  return(ql);\n}\n\nstruct queryline *db8_cacheset_flags(unsigned char *queryname, int rownum, unsigned char *set)\n{\n  int add;\n  struct queryheader *qh;\n  struct queryline **ppql;\n  \n  qh = db8_queryheader(queryname);\n\n  add = 1;\n\n  ppql = &amp;qh-&gt;first;\n\n  while(*ppql != NULL) {\n    if((qh-&gt;flags &amp; DB8_DISTINCT) &amp;&amp;\n       !strcmp(set, (*ppql)-&gt;line) ) {\n      add = 0;\n      break;\n    }\n    if((qh-&gt;flags &amp; DB8_ROWSORT) &amp;&amp;\n       db8_strcmp_num(set, (*ppql)-&gt;line) &lt; 0) {\n      \/\/strcmp(set, (*ppql)-&gt;line) &lt; 0) {\n      add = 1;\n      break;\n    }\n    ppql = &amp;((*ppql)-&gt;next);\n  }\n\n  if(add) {\n    struct queryline *ql;\n    ql = malloc(sizeof(struct queryline));\n    if((ql-&gt;line = malloc(strlen(set) + 1)) == NULL) {\n      fprintf(stderr,\"%s: cannot malloc memory\\n\", procname);\n      exit(1);\n    }\n    strcpy(ql-&gt;line, set);\n#ifdef DEBUG61\n    more_printf(stdout,\"db8_cacheset_flags:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    ql-&gt;rownum = 0;\n    ql-&gt;next = *ppql;\n    *ppql = ql;\n  }\n  \n  return(NULL);\n}\n\n#define aDEBUG62\n\nvoid db8_renumbersets(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rownum;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rownum = 0;\n  while(ql != NULL) {\n    ql-&gt;rownum = rownum;\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_renumbersets:\");\n    more_printf(stdout,\" %d:\", rownum);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rownum++;\n    ql = ql-&gt;next;\n  }\n}\n\nvoid db8_countsets(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n  int rows;\n  \n  qh = db8_queryheader(queryname);\n  ql = qh-&gt;first;\n  rows = 0;\n  while(ql != NULL) {\n#ifdef DEBUG62\n    more_printf(stdout,\"db8_countsets:\");\n    more_printf(stdout,\" %d:\", rows);\n    more_printf(stdout,\" %s\", ql-&gt;line);\n    more_printf(stdout,\"\\n\");\n#endif\n    rows++;\n    ql = ql-&gt;next;\n  }\n  qh-&gt;count = rows;\n  more_printf(stdout,\"%d rows\\n\", rows);\n}\n\nstruct queryline *db8_get_line(unsigned char *queryname, int rownum)\n{\n  struct queryheader *qh;\n  struct queryline *ql, *qline;\n  static unsigned char *row = NULL;\n  static unsigned int rowlen = 0;\n  int rownum2, count;\n  \n  FILE *fp1;\n  \n  qh = db8_queryheader(queryname);\n\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(rownum == ql-&gt;rownum) {\n      break;\n    } else if(rownum &lt; ql-&gt;rownum) {\n      ql = NULL;\n      break;\n    }\n    ql = ql-&gt;next;\n  }\n\n  if(ql == NULL &amp;&amp; qh-&gt;flags &amp;&amp; qh-&gt;count != 0)\n    return(NULL);\n\n  qline = ql;\n  if(ql == NULL) {\n    if((fp1 = fopen(db8_filename,\"r\")) == NULL) {\n      fprintf(stderr,\"%s: cannot open file, filename = %s\\n\", procname, db8_filename);\n      exit(1);\n    }\n    rownum2 = 0;\n    count = 0;\n    for(;;) {\n      if(db8_fgets(&amp;rowlen, &amp;row, fp1) == NULL)\n\tbreak;\n      if(db8_matchandproject(queryname, row)) {\n\tif(rownum2 &gt;= rownum &amp;&amp; rownum2 &lt;= rownum + qh-&gt;preread) {\n\t  if(qh-&gt;flags) {\n\t    ql = db8_cacheset_flags(queryname, rownum2, row);\n\t  } else {\n\t    ql = db8_cache_set(queryname, rownum2, row);\n\t  }\n#ifdef DEBUG65\n\t  more_printf(stdout,\"%d %s*\\n\", rownum2, row);\n#endif\n\t  if(qh-&gt;flags) \/\/ sorting --&gt; read all\n\t    continue;\n\t  if(rownum == rownum2)\n\t    qline = ql;\n\t  count++;\n\t  if(qh-&gt;preread == 0 ||\n\t     count &gt; rownum + qh-&gt;preread)\n\t    break;\n\t}\n\trownum2++;\n      }\n    }\n\n    fclose(fp1);\n\n    if(qh-&gt;flags) {\n      db8_renumbersets(queryname);\n      db8_countsets(queryname);\n      qline = qh-&gt;first;\n    }\n  }\n    \n  return(qline);\n}\n\n#define aDEBUG64 2\n#define aDEBUG68 2\n#define aDEBUG69 2\n\nint db8_get_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n \n  if(namelen == 0)\n    namelen = strlen(name);\n  \n#ifdef DEBUG5\n  fprintf(stdout,\"db8_get_element\");\n  fprintf(stdout,\", query=%s\", queryname);\n  fprintf(stdout,\", row=%d\", rownum);\n  fprintf(stdout,\", namelen=%u\", namelen);\n  fprintf(stdout,\", name=%s\", name);\n  fprintf(stdout,\", valuesize=%u\", valuesize);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  ql = db8_get_line(queryname, rownum);\n\n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n  \n    int retval = db8_get(&amp;ql-&gt;line, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval); \/\/ 2023 JariK\n  } else\n    return(0);\n}\n\nint db8_get_element_num(unsigned char *queryname, int rownum, int col, unsigned int namesize, unsigned int *namelen, unsigned char *name, unsigned int valuesize, unsigned int *valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n  \n  if(*namelen == 0)\n    *namelen = strlen(name);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8_get_element_num\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", col=%d\", col);\n    fprintf(stdout,\", namesize=%u\", namesize);\n    fprintf(stdout,\", valuesize=%u\", valuesize);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  ql = db8_get_line(queryname, rownum);\n  \/\/fprintf(stdout,\"ql:%s\\n\",ql-&gt;line);\n  \n  if(ql != NULL &amp;&amp; ql-&gt;line != NULL) {\n#ifdef DEBUG69\n    fprintf(stdout,\"db8_get_element_num:\");\n    fprintf(stdout,\" rownum:%u\", rownum);\n    fprintf(stdout,\", row:%s\", ql-&gt;line);\n#endif\n    int retval = db8_get_num(&amp;ql-&gt;line, col, namesize, namelen, name, valuesize, valuelen, value); \/\/ 2023 JariK\n#ifdef DEBUG69\n    fprintf(stdout,\", valuelen=%u\", *valuelen);\n    fprintf(stdout,\", value=%.*s\", *valuelen, value);\n    fprintf(stdout,\"\\n\");\n#endif\n    return(retval);\n  } else\n    return(0);\n}\n\nint db8_put_element(unsigned char *queryname, int rownum, unsigned int namelen, unsigned char *name, unsigned int valuelen, unsigned char *value)\n{\n  struct queryline *ql;\n  \n  if(namelen == 0)\n    namelen = strlen(name);\n  if(valuelen == 0)\n    valuelen = strlen(value);\n  \n#ifdef DEBUG5\n  if(db8_verbose) {\n    fprintf(stdout,\"db8: put_element\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\", rownum=%d\", rownum);\n    fprintf(stdout,\", namelen=%u\", namelen);\n    fprintf(stdout,\", name=%.*s\", namelen, name);\n    fprintf(stdout,\", valuelen=%u\", valuelen);\n    fprintf(stdout,\", value=%.*s\", valuelen, value);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  \n  \/\/db8_set = db8_find_set(queryname, rownum);\n\n  ql = db8_lineheader(queryname, rownum);\n  db8_put(&amp;ql-&gt;line, namelen, name, valuelen, value); \/\/ 2023 JariK\n  ql-&gt;save = 1;\n  return(0);\n}\n\nvoid db8_dump(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n  qh = db8_queryheader(queryname);\n  fprintf(stdout,\"qh=%p\", qh);\n  fprintf(stdout,\", queryname=%s\", qh-&gt;queryname);\n  fprintf(stdout,\", flags=%d\", qh-&gt;flags);\n  fprintf(stdout,\", query=%s\", qh-&gt;query);\n  fprintf(stdout,\", count=%d\", qh-&gt;count);\n  fprintf(stdout,\", preread=%d\", qh-&gt;preread);\n  fprintf(stdout,\", next=%p\", qh-&gt;next);\n  fprintf(stdout,\", first=%p\", qh-&gt;first);\n  fprintf(stdout,\"\\n\");\n  \n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    fprintf(stdout,\"ql=%p\", ql);\n    fprintf(stdout,\", rownum=%d\", ql-&gt;rownum);\n    fprintf(stdout,\", save=%d\", ql-&gt;save);\n    fprintf(stdout,\", next=%p\", ql-&gt;next);\n    fprintf(stdout,\", line=%p\", ql-&gt;line);\n    if(ql-&gt;line != NULL)\n      fprintf(stdout,\" %s\", ql-&gt;line);\n    fprintf(stdout,\"\\n\");\n    ql = ql-&gt;next;\n  }\n  fflush(stdout);\n}\n\nint db8_save(unsigned char *queryname)\n{\n  struct queryheader *qh;\n  struct queryline *ql;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save:\");\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  qh = db8_queryheader(queryname);\n\n  fprintf(stdout,\"%s\\n\", db8_set);\n\n  FILE *fp1;\n  if((fp1 = fopen(db8_filename, \"a\"))==NULL) {\n    fprintf(stdout,\"%s: db8 cannot open file '%s'\\n\", procname, db8_filename);\n    exit(1);\n  }\n  ql = qh-&gt;first;\n  while(ql != NULL) {\n    if(ql-&gt;save) {\n      fprintf(fp1,\"%s\\n\", ql-&gt;line);\n      ql-&gt;save = 0;\n    }\n    ql = ql-&gt;next;\n  }\n  \n  fclose(fp1);\n\n  db8_dump(queryname);\n\n  return(0);\n}\n\nint db8_save_all()\n{\n  struct queryheader *qh;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_save_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    db8_save(qh-&gt;queryname);\n    qh = qh-&gt;next;\n  }\n  return(0);\n}\n\nint db8_clear(unsigned char *queryname)\n{\n  struct queryheader **ppqh, *qh;\n  struct queryline *ql, *qlnext;\n  \n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"clear %s\", queryname);\n    fprintf(stdout,\", query=%s\", queryname);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n\n  ppqh = &amp;firstqueryheader;\n  while(*ppqh != NULL) {\n    if(!strcmp(queryname, (*ppqh)-&gt;queryname))\n      break;\n    ppqh = &amp;((*ppqh)-&gt;next);\n  }\n\n  if(*ppqh != NULL) {\n    qh = *ppqh;\n    ql = qh-&gt;first;\n    *ppqh = qh-&gt;next;\n    free(qh);\n    \n    while(ql != NULL) {\n      qlnext = ql-&gt;next;\n      if(ql-&gt;line != NULL)\n\tfree(ql-&gt;line);\n      free(ql);\n      ql = qlnext;\n    }\n  }\n  return(0);\n}\n\nint db8_clear_all()\n{\n  struct queryheader *qh, *qhnext;\n\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_clear_all:\\n\");\n  }\n#endif\n  \n  qh = firstqueryheader;\n  while(qh != NULL) {\n    qhnext = qh-&gt;next;\n    db8_clear(qh-&gt;queryname);\n    qh = qhnext;\n  }\n  return(0);\n}\n\nint db8_exit()\n{\n#ifdef DEBUG5\n  if(db8_verbose == 1) {\n    fprintf(stdout,\"db8_exit:\\n\");\n  }\n#endif\n  \n  return(0);\n}\n\nvoid db8_version()\n{\n  fprintf(stdout, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stdout, \", %s\", copyright);\n}\n#ifdef QUERY\n#include &lt;signal.h&gt;\n\nint ctrlcquit = 0;\n\nstatic void sig_handler()\n{\n  fprintf(stderr,\"Ctrl-c pressed\\n\");\n  ctrlcquit = 1;\n  \/\/signal(SIGINT, SIG_DFL);\n}\n\nstatic int db8_ischar(int c)\n{\n  if(isalpha(c) || isdigit(c) || c &gt;= 0x80 || c == '_')\n    return(1);\n  else\n    return(0);\n}\n\nint db8_isquote(int c)\n{\n  if(ispunct(c) &amp;&amp; c != ',' &amp;&amp; c != '=')\n    return(1);\n  else\n    return(0);\n}\n\n#define aDEBUG60\n\nstatic int namequote = -1, valuequote = -1;\n\nstatic void db8_get_element3(int *namelen, unsigned char **name, int *valuelen, unsigned char **value, unsigned char **p2) \/\/ 2023 JariK\n{\n  unsigned char *p;\n\n  p = *p2;\n  \n  db8_skipwhite(&amp;p);\n\n  if(namequote == -1) {\n    if(db8_isquote(*p))\n      namequote = *p;\n    else\n      namequote = 0;\n  }\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 1 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *namelen = -1;\n  if((*p == namequote &amp;&amp; namequote) ||\n     (db8_ischar(*p) &amp;&amp; !namequote)) { \/\/ name\n    *namelen = 0;\n#ifdef DEBUG60\n    fprintf(stdout,\"db8_get_element: 2 %s\\n\", p);\n#endif\n    if(namequote) {\n      p++;\n      *name = p;\n      while(*p != namequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 3 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n      if(*p == namequote)\n\tp++;\n    } else {\n      *name = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 4 %s\\n\", p);\n#endif\n\tp++;\n\t(*namelen)++;\n      }\n    }\n  } else\n    *name = NULL;\n\n  db8_skipwhite(&amp;p);\n  if(*p == '=') {\n    p++;\n    db8_skipwhite(&amp;p);\n  }\n\n  if(valuequote == -1) {\n    if(db8_isquote(*p))\n      valuequote = *p;\n    else\n      valuequote = 0;\n  }\n  \n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 5 %s %c(%d)\\n\", p, valuequote, valuequote);\n#endif\n  *valuelen = -1;\n  if((*p == valuequote &amp;&amp; valuequote) ||\n     (db8_ischar(*p) &amp;&amp; !valuequote)) { \/\/ value\n    *valuelen = 0;\n    if(valuequote) {\n      p++;\n#ifdef DEBUG60\n      fprintf(stdout,\"db8_get_element: 6 %s\\n\", p);\n#endif\n      *value = p;\n      while(*p != valuequote &amp;&amp; *p != '\\0') {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 7 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n      if(*p == valuequote)\n\tp++;\n    } else {\n      *value = p;\n      while(db8_ischar(*p)) {\n#ifdef DEBUG60\n\tfprintf(stdout,\"db8_get_element: 8 %s\\n\", p);\n#endif\n\tp++;\n\t(*valuelen)++;\n      }\n    }\n  } else\n    *value = NULL;\n\n  db8_skipwhite(&amp;p);\n\n#ifdef DEBUG60\n  fprintf(stdout,\"db8_get_element: 9 %s\\n\", p);\n#endif\n  *p2 = p;\n}\n\nvoid db8_squery(unsigned char *query) \/\/ JariK 2025 single\n{\n  int row, col, first, ok, print;\n\n  unsigned int namelen;\n  unsigned int valuelen;\n  unsigned char *name, *value;\n\n  unsigned char *q;\n  unsigned char *query2 = NULL;\n\n  if(more)\n    more_init(); \/\/ adjust thee screensize\n  \n  q = query;\n  fprintf(stdout,\"query:%s\\n\", query);\n  fflush(stdout);\n\n  namequote = -1;\n  valuequote = -1;  \n  while(*q != '\\0') {\n    db8_skipwhite(&amp;q);\n    db8_get_element3(&amp;namelen, &amp;name, &amp;valuelen, &amp;value, &amp;q);\n    if(name == NULL)\n      break;\n    db8_skipwhite(&amp;q);\n    if(*q == ',') {\n      q++;\n      db8_skipwhite(&amp;q);\n    }\n    fprintf(stderr,\"db8_squery():\");\n    fprintf(stderr,\" name:%.*s(%d)\", namelen, name, namelen);\n    fprintf(stderr,\", value:%.*s(%d)\", valuelen, value, valuelen);\n    fprintf(stderr,\"\\n\");\n    db8_put(&amp;query2, namelen, name, valuelen, value);\n  }\n  db8_set_filename(db8_filename);\n  fprintf(stdout,\"query2:%s\\n\", query2);\n  db8_clear(\"query\");\n  db8_set_query(\"query\", query2);\n  \/\/db8_set_queryflags(\"query\", 0);\n  \/\/db8_set_queryflags(\"query\", DB8_DISTINCT);\n  db8_set_queryflags(\"query\", DB8_ROWSORT | DB8_DISTINCT);\n  free(query2);\n  row = 0;\n\n  unsigned int namesize2, namelen2, valuesize2, valuelen2;\n  unsigned char name2&#91;128], value2&#91;128];\n\n  namesize2 = sizeof(name2);\n  valuesize2 = sizeof(value2);\n\n  for(;;) {\n\n    morequit = 0;\n    print = 0;\n    first = 1;\n    col = 0;\n    ok = 0;\n    for(;;) {\n      \/\/fprintf(stdout,\"row:%d, col:%d, \", row, col);\n      \n      if(db8_get_element_num(\"query\", row, col, namesize2, &amp;namelen2, name2, valuesize2, &amp;valuelen2, value2))\n\tok = 1;\n      else\n\tbreak;\n\n      if(col == 0)\n\tfprintf(stdout,\"%d \", row);\n      \n      if(!first)\n\tfprintf(stdout,\", \");\n\n      print = 1;\n      \n      more_printf(stdout,\"'%s' = \\\"%s\\\"\", name2, value2);\n      fflush(stdout);\n      col++;\n      first = 0;      \n    }\n    if(print) {\n      more_printf(stdout,\"\\n\");\n      fflush(stdout);\n    }\n    \n    if(!ok)\n      break;\n    if(more &amp;&amp; morequit)\n      break;\n    if(ctrlcquit) {\n      ctrlcquit = 0;\n      break;\n    }\n\n    row++;\n  }\n  \/\/db8_dump(\"query\");\n}\n\nunsigned char prompt&#91;128] = \"skk&gt;\";\n\nstatic int db8_isword(unsigned char **p2, unsigned char *word)\n{\n  unsigned char *p;\n\n  int wlen = strlen(word);\n  \n  p = *p2;\n  db8_skipwhite(&amp;p);\n  if(!strncmp(word, p, wlen) &amp;&amp;\n     ( (isblank(*(p + wlen))) ||\n       (ispunct(*(p + wlen))) ||\n       (*(p + wlen) == '\\0') ) ) {\n    p += wlen;\n    db8_skipwhite(&amp;p);\n    *p2 = p;\n    return(1);\n  } else\n    return(0);\n}\n\nvoid db8_iquery() \/\/ JariK 2025 interactive\n{\n  unsigned char *command = NULL, *p;\n  int commandsize = 0;\n\n  ctrlcquit = 0;\n  signal(SIGINT, sig_handler);\n  fprintf(stdout,\"%s\\n\", programname);\n  \n  for(;;) {\n    fprintf(stdout, \"%s\", prompt);\n    db8_fgets(&amp;commandsize, &amp;command, stdin);\n    p = command;\n    db8_skipwhite(&amp;p);\n    if(*p == '\\0')\n       continue;\n    if(db8_isword(&amp;p, \"more\")) {\n      if(db8_isword(&amp;p, \"on\")) {\n\tmore = 1;\n\tcontinue;\n      }\n      if(db8_isword(&amp;p, \"off\")) {\n\tmore = 0;\n\tcontinue;\n      }\n      more = !more;\n      fprintf(stderr,\"more \");\n      if(more)\n\tfprintf(stderr,\"on\");\n      else\n\tfprintf(stderr,\"off\");\n      fprintf(stderr,\"\\n\");\n      continue;\n    }\n    if(db8_isword(&amp;p, \"exit\"))\n      break;\n    if(db8_isword(&amp;p, \"quit\"))\n      break;\n    db8_squery(p);\n  }\n  signal(SIGINT, SIG_DFL);\n}\n\n#endif\n\n#ifdef MAIN\n\nunsigned char *procname;\n\nchar *query = NULL;\nunsigned char filename&#91;128] = \"newressusudoku.skk.db\";\n\nint main(int argc, char *argv&#91;])\n{\n  int c, args = 0, help = 0;\n  \n  procname = argv&#91;0];\n\n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n    \n    if(!strcmp(\"--help\", argv&#91;c])) {\n      help = 1;\n\n    } else if(!strcmp(\"--args\", argv&#91;c])) {\n      args = !args;\n\n    } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t      !strcmp(\"--version\", argv&#91;c])) {\n      fprintf(stderr, \"%s\", programname);\n      fprintf(stderr, \", %s\\n\", copyright);\n      exit(0);\n      \n    } else if(!strncmp(\"--skkfile\", argv&#91;c], 9)) { \/\/ JariK 2025\n      if(*(argv&#91;c] + 9) != '\\0') {\n\tstrcpy(filename, argv&#91;c] + 9);\n      } else if(c + 1 &lt; argc) {\n\tstrcpy(filename, argv&#91;c + 1]);\n\tc++;\n      }\n\n    } else if(!strncmp(\"--query\", argv&#91;c], 7)) { \/\/ JariK 2025\n      query = NULL;\n      if(*(argv&#91;c] + 7) != '\\0') {\n\tquery = argv&#91;c] + 7;\n      } else if(c + 1 &lt; argc &amp;&amp; *(argv&#91;c + 1]) != '-') {\n\tquery = argv&#91;c + 1];\n\tc++;\n      }\n      \n    } else if(!strncmp(\"--more\", argv&#91;c], 6)) { \/\/ JariK 2025\n      more = !more;\n\n    }\n  }\n\n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--skkfile&#91;filename]]\");\n    fprintf(stderr,\" &#91;--query&#91;querytext]]\");\n    fprintf(stderr,\" &#91;--more]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  if(args) {\n    fprintf(stderr,\"argc: %d\\n\", argc);\n    for(c = 0; c &lt; argc; c++) {\n      fprintf(stderr,\"argv&#91;%d]: %s\\n\", c, argv&#91;c]);\n    }\n    exit(1);\n  }\n\n#ifdef TEST\n\n  unsigned long l = 0;\n  c = 0;\n  for(;;) {\n    unsigned long oldl = l;\n    l = l * 10 + 9;\n    fprintf(stdout,\"%d %lu\\n\", c++, l);\n    if((l - 9) \/ 10 != oldl)\n      break;\n  }\n\n#endif\n  \n#ifdef TEST\n\n  fprintf(stdout,\"1:%ld\\n\", db8_strcmp_num(\"1\",\"1\"));\n  fprintf(stdout,\"2:%ld\\n\", db8_strcmp_num(\"a\",\"a\"));\n\n#endif\n\n  db8_set_filename(filename);\n  \n  if(query !=NULL)\n    db8_squery(query);\n  else\n    db8_iquery();\n\n  exit(0);\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 more toiminto db8 query:lle: ohjelman esittely.<\/p>\n\n\n\n<p>startprompt()  laittaa p\u00e4\u00e4tteen echon (ECHO) ja rivi (ICANON) inputin pois p\u00e4\u00e4lt\u00e4. T\u00e4t\u00e4 kutsutaan kun tulostetaan more prompti &#8220;&#8212;more&#8212;&#8220;. Kutsun j\u00e4lkeen luetaan n\u00e4pp\u00e4imist\u00f6\u00e4, ja n\u00e4it\u00e4 merkkej\u00e4 ei tulosteta ja merkit luetaan yksitt\u00e4in.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct termios old, new;\n\nvoid startprompt()\n{\n  setvbuf(stdout, NULL, _IONBF, 0);\n  tcgetattr(0, &amp;old);\n  new = old;\n  new.c_lflag &amp;= ~(ICANON | ECHO);\n  \/\/new.c_lflag &amp;= ~(ISIG | ICANON | ECHO);\n  new.c_cc&#91;VMIN] = 1;\n  new.c_cc&#91;VTIME] = 2;\n  tcsetattr(0, TCSANOW, &amp;new);\n}<\/code><\/pre>\n\n\n\n<p>endprompt muuttaa p\u00e4\u00e4tteen k\u00e4ytt\u00e4misen takaisin normaaliksi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void endprompt()\n{\n  tcsetattr(0, TCSANOW, &amp;old);\n}<\/code><\/pre>\n\n\n\n<p>Ohjelma ylikirjoittaa halutun merkkim\u00e4\u00e4r\u00e4n backspace, v\u00e4lily\u00f6nti, backspace merkeill\u00e4: t\u00e4ll\u00e4 poistetaan &#8220;&#8212;more&#8212;&#8221; sen j\u00e4lkeen kun n\u00e4pp\u00e4imist\u00f6\u00e4 on painettu.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void more_backspacechars(int chars)\n{\n  int c;\n  \n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\" \");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n}<\/code><\/pre>\n\n\n\n<p>more_init() hakee ruudun leveyden ja korkeuden more toimintoa varten: maxchars:iin laitetaan ruudun leveys ja maxlines:iin ruudun korkeus.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int screenlinesleft = 0, screenmaxchars, screenmaxlines;\nint screenchars = 0;\nint morequit = 0;\n\n#include &lt;sys\/ioctl.h&gt; \/\/ for TIOCGWINSZ\n\nvoid more_init()\n{\n  struct winsize w;\n  ioctl(0, TIOCGWINSZ, &amp;w);\n  screenmaxchars = w.ws_col;\n  screenmaxlines = w.ws_row - 1;\n  screenlinesleft = screenmaxlines;\n}<\/code><\/pre>\n\n\n\n<p>more_wait() tulostaa more tekstin (&#8220;&#8212;more&#8212;&#8220;), muuttaa p\u00e4\u00e4tteen sopivaksi ja j\u00e4\u00e4 odottamaan merkkej\u00e4. Merkkej\u00e4 odotetaan kunnes k\u00e4ytt\u00e4j\u00e4 antaa v\u00e4lily\u00f6nnin (yksi n\u00e4ytt\u00f6 lis\u00e4\u00e4), new linen (yksi rivi ils\u00e4\u00e4) tai &#8216;q&#8217;:n lopeta tuloste. Merkin j\u00e4lkeen muutetaan p\u00e4\u00e4te takaisin ja poistetaan more teksti.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void more_wait()\n{\n  int c;\n  unsigned char *moretext = \"---more---\";\n  \n  fprintf(stderr,\"%s\", moretext);\n\n  if(more) {\n    startprompt();\n\n  \/\/ wait until something below is pressed\n  \n    for(;;) {\n      c = getchar();\n      if(c == ' ') {\n\tmore_init(); \/\/ adjust for screensize\n\tscreenlinesleft = screenmaxlines; \/\/ full screen\n\tbreak;\n      } else if(c == '\\n') {\n\tscreenlinesleft = 1; \/\/ one line\n\tbreak;\n      } else if(c == 'q') { \/\/ quit\n\tmorequit = 1;\n\tbreak;\n      }\n    }\n  \n    more_backspacechars(strlen(moretext));\n  \n    endprompt();\n  }\n}<\/code><\/pre>\n\n\n\n<p>more_printf tulostaa merkkijonon siten, ett\u00e4 tulostuksen aikana tulostetaan more teksti\u00e4 ja odotetaan n\u00e4pp\u00e4imist\u00f6\u00e4 tarvittaessa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdarg.h&gt;\n\nvoid more_printf(FILE *fp1, const char *format, ...)\n{\n  int count;\n  va_list args;\n  unsigned char *p;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args, format);\n  count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf = realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ prompt more for full screen pages.\n  \n  p = printbuf;\n  while(*p!='\\0') {\n    fputc(*p, fp1);\n    if(*p=='\\n' || ++screenchars==screenmaxchars) {\n      screenchars = 0;\n      if(more &amp;&amp; --screenlinesleft == 0) {\n\tmore_wait();\n      }\n    }\n    p++;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Ja kokonainen more.c sorsa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;string.h&gt;\n#include &lt;malloc.h&gt;\n\n#include &lt;termios.h&gt;\n\nstatic unsigned char *programname = \"more version 0.1 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nstruct termios old, new;\n\nvoid startprompt()\n{\n  setvbuf(stdout, NULL, _IONBF, 0);\n  tcgetattr(0, &amp;old);\n  new = old;\n  new.c_lflag &amp;= ~(ICANON | ECHO);\n  \/\/new.c_lflag &amp;= ~(ISIG | ICANON | ECHO);\n  new.c_cc&#91;VMIN] = 1;\n  new.c_cc&#91;VTIME] = 2;\n  tcsetattr(0, TCSANOW, &amp;new);\n}\n\nvoid endprompt()\n{\n  tcsetattr(0, TCSANOW, &amp;old);\n}\n\nvoid more_backspacechars(int chars)\n{\n  int c;\n  \n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\" \");\n  for(c = 0; c &lt; chars; c++)\n    fprintf(stdout,\"\\b\");\n}\n\nint more = 1;\n\nint screenlinesleft = 0, screenmaxchars, screenmaxlines;\nint screenchars = 0;\nint morequit = 0;\n\n#include &lt;sys\/ioctl.h&gt; \/\/ for TIOCGWINSZ\n\nvoid more_init()\n{\n  struct winsize w;\n  ioctl(0, TIOCGWINSZ, &amp;w);\n  screenmaxchars = w.ws_col;\n  screenmaxlines = w.ws_row - 1;\n  screenlinesleft = screenmaxlines;\n}\n\nvoid more_version()\n{\n  fprintf(stderr, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stderr, \", %s\", copyright);\n}\n\nvoid more_wait()\n{\n  int c;\n  unsigned char *moretext = \"---more---\";\n  \n  fprintf(stderr,\"%s\", moretext);\n\n  if(more) {\n    startprompt();\n\n  \/\/ wait until something below is pressed\n  \n    for(;;) {\n      c = getchar();\n      if(c == ' ') {\n\tmore_init(); \/\/ adjust for screensize\n\tscreenlinesleft = screenmaxlines; \/\/ full screen\n\tbreak;\n      } else if(c == '\\n') {\n\tscreenlinesleft = 1; \/\/ one line\n\tbreak;\n      } else if(c == 'q') { \/\/ quit\n\tmorequit = 1;\n\tbreak;\n      }\n    }\n  \n    more_backspacechars(strlen(moretext));\n  \n    endprompt();\n  }\n}\n\n#include &lt;stdarg.h&gt;\n\nvoid more_printf(FILE *fp1, const char *format, ...)\n{\n  int count;\n  va_list args;\n  unsigned char *p;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args, format);\n  count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf = realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count = vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n  \/\/ print all characters from printbuf.\n  \/\/ prompt more for full screen pages.\n  \n  p = printbuf;\n  while(*p!='\\0') {\n    fputc(*p, fp1);\n    if(*p=='\\n' || ++screenchars==screenmaxchars) {\n      screenchars = 0;\n      if(more &amp;&amp; --screenlinesleft == 0) {\n\tmore_wait();\n      }\n    }\n    p++;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 newressusudoku ohjelman kokonainen sorsa: ($ cc -DSHA256 newressusudoku.c newressu.c sha256.c -o newressusudoku -lm)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n\nunsigned char *procname;\nstatic unsigned char *programname = \"newressusudoku version 0.7 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2025 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#include &lt;errno.h&gt;\n#include &lt;semaphore.h&gt;\n#include &lt;fcntl.h&gt;\n\n#define USE_SEMAPHORES 2\n\n#ifdef USE_SEMAPHORES\n\nstatic sem_t *mutex;\nstatic char *semname = \"sudokusemaphore\";\n\n#define DEBUG17 2\n\nvoid my_sem_open()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_open():\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_unlink()\");\n#endif\n  if(sem_unlink(semname) == 0) {\n    fprintf(stdout, \"%s: previous semaphore %s removed\\n\", procname, semname);\n  }\n  \n#ifdef DEBUG17\n  fprintf(stderr,\", sem_open()\\n\");\n#endif\n  if((mutex = sem_open(semname, O_CREAT, 0644, 1)) == SEM_FAILED) {\n    \/\/if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {\n    fprintf(stderr, \"\\n%s: cannot sem_open()\", procname);\n    fprintf(stderr,\" errno %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr, \"\\n\");\n    perror(\"sem_open\");\n  }\n}\n\nvoid my_sem_wait()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_wait():\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_wait()\\n\");\n#endif\n  if(sem_wait(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_wait()\", procname);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_wait\");\n  }\n}\n\nvoid my_sem_post()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_post():\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\"  sem_post()\\n\");\n#endif\n  if(sem_post(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_post()\", procname);\n    fprintf(stderr, \", errno: %d\\n\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    perror(\"sem_post\");\n  }\n}\n\nvoid my_sem_close()\n{\n#ifdef DEBUG17\n  fprintf(stderr,\"my_sem_close():\");\n#endif\n\n#ifdef DEBUG17\n  fprintf(stderr,\" sem_unlink()\");\n#endif\n  sem_unlink(semname);\n\n#ifdef DEBUG17\n  fprintf(stderr,\" sem_close()\\n\");\n#endif\n  sem_close(mutex);\n}\n\n#endif\n\n#define GENT_SIZE 1024\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\nint sudoku_output = 0;\n\nunsigned char *key = NULL;\n\nvoid pseudoressu_bytes(int size, unsigned char *buffer);\nvoid stream_bytes(int size, unsigned char *buffer);\nvoid stream_open(int size, unsigned char *key); \/\/ size = 0 --&gt; zero terminated string\n\nint newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    memset(gent, 0, sizeof(gent));\n    if(key == NULL)\n      pseudoressu_bytes(sizeof(gent), gent);\n    else\n      stream_bytes(sizeof(gent), gent);\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\nunsigned long newressu_gen_limit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n#define aDEBUG4 2\n\n#ifdef DEBUG4\n  fprintf(stdout,\"limit:%lu\", limit);\n  fprintf(stdout,\", highlimit:%lu\", highlimit);\n  fprintf(stdout,\", bytes:%d\", bytes);\n  fprintf(stdout,\", word:%lu\", word);\n  fprintf(stdout,\", word%%limit:%lu\\n\", (unsigned long) word % limit);\n#endif\n  \n  word %= limit;\n\n  return(word);\n}\n\nint digitsa = -1;\nint digitsb = -1;\n\nunsigned char *cross =\n  \"111222111\"\n  \"111222111\"\n  \"111222111\"\n  \"222111222\"\n  \"222111222\"\n  \"222111222\"\n  \"111222111\"\n  \"111222111\"\n  \"111222111\";\n\nunsigned char *plus =\n  \"222111222\"\n  \"222111222\"\n  \"222111222\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"222111222\"\n  \"222111222\"\n  \"222111222\";\n\nunsigned char *slashes =\n  \"001001001\"\n  \"010010010\"\n  \"100100100\"\n  \"001001001\"\n  \"010010010\"\n  \"100100100\"\n  \"001001001\"\n  \"010010010\"\n  \"100100100\";\n\nunsigned char *full =\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\"\n  \"111111111\";\n\nunsigned char *sudoku_grid1 = NULL;\n\nvoid sudoku_get_choices(unsigned char b&#91;82], int cell, char choices2&#91;10])\n{\n  int c, d, lin, col, box;\n  char choices&#91;10], digit&#91;2], digits&#91;]=\"123456789\";\n\n  lin = cell \/ 9;\n  col = cell % 9;\n  box = lin \/ 3 * 27 + col \/ 3 * 3;\n  \n  choices&#91;0] = '\\0';\n  \n  for(c = 0; c &lt; 9; c++) {\n    if(b&#91;lin * 9 + c] != ' ' &amp;&amp; strchr(choices, b&#91;lin * 9 + c]) == NULL) {\n      digit&#91;0] = b&#91;lin * 9 + c];\n      digit&#91;1] = '\\0';\n      strcat(choices, digit);\n    }\n  }\n  \n  for(c = 0; c &lt; 9; c++) {\n    if(b&#91;c * 9 + col] != ' ' &amp;&amp; strchr(choices, b&#91;c * 9 + col]) == NULL) {\n      digit&#91;0] = b&#91;c * 9 + col];\n      digit&#91;1] = '\\0';\n      strcat(choices, digit);\n    }\n  }\n  \n  for(c = 0; c &lt; 3; c++) {\n    for(d = 0; d &lt; 3; d++) {\n      if(b&#91;box + c * 9 + d] != ' ' &amp;&amp; strchr(choices, b&#91;box + c * 9 + d]) == NULL) {\n\tdigit&#91;0] = b&#91;box + c * 9 + d];\n\tdigit&#91;1] = '\\0';\n\tstrcat(choices, digit);\n      }\n    }\n  }\n  \n  choices2&#91;0] = '\\0';\n\n  for(c = 0; c &lt; 9; c++) {\n    if(strchr(choices, digits&#91;c]) == NULL) {\n      digit&#91;0] = digits&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(choices2, digit);\n    }\n  }\n}\n\nint space = 1;\n\n\/*\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA |           |     2     |         7 |\nB |           |     6     |           |\nC | 5   3     | 8   4   7 | 2         |\n  +-----------+-----------+-----------+\nD | 2         |         8 |     1   9 |\nE |           |           |           |\nF | 1       8 |     9     | 7   6   3 |\n  +-----------+-----------+-----------+\nG |     9     | 7         |           |\nH |           | 9   1     |         5 |\nI |     4     |         6 | 9         |\n  +-----------+-----------+-----------+\n                              steps:209\n*\/\n\nvoid sudoku_board(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \"    A   B   C   D   E   F   G   H   I  \\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"|\\n\");\n    }\n    if(c % 27 == 0)\n      strcat(s,\"  +-----------+-----------+-----------+\\n\");\n    if(c % 9 == 0) {\n      sprintf(line,\"%c \",'A' + c \/ 9);\n      strcat(s, line);\n    }\n    if(c % 3 == 0) {\n      strcat(s, \"|\");\n    } else strcat(s, \" \");\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\" %c \", b&#91;c]);\n    else\n      sprintf(line,\"   \");\n    strcat(s, line);\n  }\n  strcat(s, \"|\\n  +-----------+-----------+-----------+\");\n  strcat(s, \"\\n\");\n}\n\n\/*\n  ABC DEF GHI \n +---+---+---+\nA|   |   |   |\nB|   | 26|   |\nC|8 7|13 |6 2|\n +---+---+---+\nD|7  |  3|1  |\nE| 52|6 7|9  |\nF|   |   |   |\n +---+---+---+\nG|3  |7 8|49 |\nH|4 9|   |  7|\nI|   |  1| 36|\n +---+---+---+\n *\/\nvoid sudoku_board2(char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \"  ABC DEF GHI \\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"|\\n\");\n    }\n    if(c % 27 == 0)\n      strcat(s, \" +---+---+---+\\n\");\n    if(c % 9 == 0) {\n      sprintf(line,\"%c\",'A' + c \/ 9);\n      strcat(s, line);\n    }\n    if(c % 3 == 0) {\n      strcat(s, \"|\");\n    }\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\"%c\", b&#91;c]);\n    else\n      sprintf(line,\" \");\n    strcat(s, line);\n  }\n  strcat(s, \"|\\n +---+---+---+\");\n  strcat(s, \"\\n\");\n}\n\n\/*\n  ABCDEFGHI \n +---------+\nA|573842619|\nB|219675348|\nC|684319275|\nD|821453967|\nE|937168524|\nF|456297831|\nG|145936782|\nH|392781456|\nI|768524193|\n +---------+\n  *\/\nvoid sudoku_board3(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \"  ABCDEFGHI \\n\");\n  strcat(s,\" +---------+\\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"|\\n\");\n    }\n    if(c % 9 == 0) {\n      sprintf(line,\"%c\",'A' + c \/ 9);\n      strcat(s, line);\n    }\n    if(c % 9 == 0) {\n      strcat(s, \"|\");\n    }\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\"%c\", b&#91;c]);\n    else\n      sprintf(line,\" \");\n    strcat(s, line);\n  }\n  strcat(s, \"|\\n +---------+\");\n  strcat(s, \"\\n\");\n}\n\n\/*\n  ABCDEFGHI\n +---------\nA|695217483\nB|138564792\nC|724893156\nD|572946318\nE|463185279\nF|981732645\nG|357429861\nH|846351927\nI|219678534\n *\/\nvoid sudoku_board4(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \"  ABCDEFGHI\\n\");\n  strcat(s,\" +---------\\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0)\n      strcat(s,\"\\n\");\n\n    if(c % 9 == 0) {\n      sprintf(line,\"%c\",'A' + c \/ 9);\n      strcat(s, line);\n    }\n    if(c % 9 == 0)\n      strcat(s, \"|\");\n\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\"%c\", b&#91;c]);\n    else\n      sprintf(line,\" \");\n    strcat(s, line);\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\n ABCDEFGHI \nA287935641\nB615482379\nC943761258\nD324519867\nE596874123\nF178623495\nG432197586\nH761258934\nI859346712\n *\/\nvoid sudoku_board5(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  strcat(s, \" ABCDEFGHI \\n\");\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0)\n      strcat(s,\"\\n\");\n\n    if(c % 9 == 0) {\n      sprintf(line,\"%c\",'A' + c \/ 9);\n      strcat(s, line);\n    }\n\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\"%c\", b&#91;c]);\n    else\n      sprintf(line,\" \");\n\n    strcat(s, line);\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\n435189627\n691275384\n872436591\n349852176\n168947235\n257613849\n914368752\n723591468\n586724913\n *\/\nvoid sudoku_board6(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char line&#91;128];\n  \n  *s='\\0';\n\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"\\n\");\n    }\n    if(b&#91;c] != ' ' &amp;&amp; b&#91;c] != '0')\n      sprintf(line,\"%c\", b&#91;c]);\n    else\n      sprintf(line,\" \");\n    strcat(s, line);\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\nAA5 AB28 AC3 AD1 AE9 AF278 AG4 AH367 AI678\nBA6 BB248 BC7 BD23 BE23 BF28 BG389 BH1 BI589\nCA138 CB9 CC13 CD367 CE4 CF5 CG2 CH367 CI678\nDA13479 DB14567 DC2 DD69 DE16 DF149 DG369 DH8 DI4679\nEA1479 EB1467 EC1469 ED269 EE8 EF3 EG5 EH2679 EI24679\nFA3489 FB468 FC3469 FD5 FE7 FF249 FG369 FH2369 FI1\nGA12479 GB12457 GC1459 GD8 GE1235 GF6 GG19 GH259 GI259\nHA1279 HB3 HC1569 HD279 HE125 HF1279 HG1689 HH4 HI25689\nIA129 IB1256 IC8 ID4 IE125 IF129 IG7 IH2569 II3\n *\/\nvoid sudoku_board10(unsigned char *s, unsigned char b&#91;82])\n{\n  int c, first;\n  unsigned char choices&#91;10], line&#91;128];\n  \n  *s='\\0';\n  first = 1;\n  for(c = 0; c &lt; 81; c++) {\n    if(c &gt; 0 &amp;&amp; c % 9 == 0) {\n      strcat(s,\"\\n\");\n      first = 1;\n    }\n    if(!first)\n      strcat(s, \" \");\n    sprintf(line,\"%c%c\",'A' + c \/ 9, 'A' + c % 9);\n    strcat(s, line);\n\n    if(b&#91;c] &gt;= '1' &amp;&amp; b&#91;c] &lt;= '9') {\n      unsigned char digit&#91;3];\n      digit&#91;0] = b&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(s, digit);\n    } else {\n      sudoku_get_choices(b, c, choices);\n      strcat(s, choices);\n    }\n    first = 0;\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\n    7   37     1 88     95  78  1 4 21      595 6   3 4  23     6   7 1      5 9 \n *\/\nvoid sudoku_board11(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char digit&#91;3];\n\n  *s='\\0';\n  for(c = 0; c &lt; 81; c++) {\n    if(b&#91;c] &gt;= '1' &amp;&amp; b&#91;c] &lt;= '9') {\n      digit&#91;0] = b&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(s, digit);\n    } else\n      strcat(s, \" \");\n  }\n  strcat(s, \"\\n\");\n}\n\/*\n  030010000090407200000026100005000000809140700000000020072953804060000300000000507\n*\/\nvoid sudoku_board12(unsigned char *s, unsigned char b&#91;82])\n{\n  int c;\n  unsigned char digit&#91;3];\n\n  *s='\\0';\n  for(c = 0; c &lt; 81; c++) {\n    if(b&#91;c] &gt;= '1' &amp;&amp; b&#91;c] &lt;= '9') {\n      digit&#91;0] = b&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(s, digit);\n    } else\n      strcat(s, \"0\");\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\n'AA' = \"4\", 'AB' = \"9\", 'AE' = \"7\", 'BA' = \"5\", 'CB' = \"8\", 'CE' = \"2\", 'CF' = \"4\", 'CG' = \"3\", 'DC' = \"9\", 'DE' = \"4\", 'DH' = \"6\", 'EB' = \"6\", 'EE' = \"5\", 'FD' = \"8\", 'FF' = \"3\", 'FH' = \"1\", 'GA' = \"3\", 'GC' = \"4\", 'GE' = \"9\", 'GI' = \"2\", 'HC' = \"6\", 'HG' = \"8\", 'IA' = \"9\", 'IB' = \"5\", 'ID' = \"2\", 'IF' = \"6\", 'II' = \"3\"\n *\/\nvoid sudoku_board20(unsigned char *s, unsigned char b&#91;82])\n{\n  int c, first = 1;\n  unsigned char column&#91;128], digit&#91;3];\n\n  *s='\\0';\n  for(c = 0; c &lt; 81; c++) {\n    if(b&#91;c] &gt;= '1' &amp;&amp; b&#91;c] &lt;= '9') {\n      column&#91;0] = '\\0';\n      if(!first)\n\tstrcat(column, \", \");\n\t\n      sprintf(column + strlen(column), \"'%c%c'\",'A' + c \/ 9, 'A' + c % 9);\n      digit&#91;0] = b&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(column, \" = \\\"\");\n      strcat(column, digit);\n      strcat(column, \"\\\"\");\n      first = 0;\n      strcat(s, column);\n    }\n  }\n  strcat(s, \"\\n\");\n}\n\n\/*\n'AA' = \"278\", 'AB' = \"1\", 'AC' = \"2358\", 'AD' = \"29\", 'AE' = \"278\", 'AF' = \"4\", 'AG' = \"237\", 'AH' = \"2357\", 'AI' = \"6\", 'BA' = \"24678\", 'BB' = \"245678\", 'BC' = \"2458\", 'BD' = \"26\", 'BE' = \"2678\", 'BF' = \"3\", 'BG' = \"247\", 'BH' = \"1\", 'BI' = \"9\", 'CA' = \"9\", 'CB' = \"23467\", 'CC' = \"234\", 'CD' = \"126\", 'CE' = \"5\", 'CF' = \"267\", 'CG' = \"2347\", 'CH' = \"8\", 'CI' = \"37\", 'DA' = \"28\", 'DB' = \"289\", 'DC' = \"7\", 'DD' = \"23569\", 'DE' = \"1\", 'DF' = \"2569\", 'DG' = \"2389\", 'DH' = \"4\", 'DI' = \"35\", 'EA' = \"5\", 'EB' = \"2489\", 'EC' = \"6\", 'ED' = \"239\", 'EE' = \"237\", 'EF' = \"279\", 'EG' = \"123789\", 'EH' = \"2379\", 'EI' = \"137\", 'FA' = \"3\", 'FB' = \"29\", 'FC' = \"129\", 'FD' = \"259\", 'FE' = \"4\", 'FF' = \"8\", 'FG' = \"6\", 'FH' = \"2579\", 'FI' = \"157\", 'GA' = \"478\", 'GB' = \"345789\", 'GC' = \"34589\", 'GD' = \"345\", 'GE' = \"3\", 'GF' = \"1\", 'GG' = \"379\", 'GH' = \"6\", 'GI' = \"2\", 'HA' = \"1267\", 'HB' = \"235679\", 'HC' = \"12359\", 'HD' = \"8\", 'HE' = \"236\", 'HF' = \"256\", 'HG' = \"1379\", 'HH' = \"379\", 'HI' = \"4\", 'IA' = \"1246\", 'IB' = \"2346\", 'IC' = \"1234\", 'ID' = \"7\", 'IE' = \"9\", 'IF' = \"26\", 'IG' = \"5\", 'IH' = \"3\", 'II' = \"8\"\n *\/\nvoid sudoku_board21(unsigned char *s, unsigned char b&#91;82])\n{\n  int c, first = 1;\n  unsigned char column&#91;128], digit&#91;3], choices&#91;10];\n\n  *s='\\0';\n  for(c = 0; c &lt; 81; c++) {\n    column&#91;0] = '\\0';\n    if(!first)\n      strcat(column, \", \");\n\t\n    sprintf(column + strlen(column), \"'%c%c' = \", 'A' + c \/ 9, 'A' + c % 9);\n\n    if(b&#91;c] &gt;= '1' &amp;&amp; b&#91;c] &lt;= '9') {\n      digit&#91;0] = b&#91;c];\n      digit&#91;1] = '\\0';\n      strcat(column, \"\\\"\");\n      strcat(column, digit);\n      strcat(column, \"\\\"\");\n    } else {\n      sudoku_get_choices(b, c, choices);\n      strcat(column, \"\\\"\");\n      strcat(column, choices);\n      strcat(column, \"\\\"\");\n    }\n    first = 0;\n    strcat(s, column);\n  }\n  strcat(s, \"\\n\");\n}\n\nint board1 = 0;\nint board2 = 0;\nint board3 = 0;\nint board4 = 0;\nint board5 = 0;\nint board6 = 0;\nint board10 = 0;\nint board11 = 0;\nint board12 = 0;\nint board20 = 0;\nint board21 = 0;\n\nvoid sudoku_print(unsigned char *b)\n{\n  unsigned char string&#91;2048];\n\n  string&#91;0] = '\\0';\n  \n  \/* zero -&gt; no board *\/\n  if(board1) {\n    sudoku_board(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board2) {\n    sudoku_board2(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board3) {\n    sudoku_board3(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board4) {\n    sudoku_board4(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board5) {\n    sudoku_board5(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board6) {\n    sudoku_board6(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board10) {\n    sudoku_board10(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board11) {\n    sudoku_board11(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board12) {\n    sudoku_board12(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board20) {\n    sudoku_board20(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n  if(board21) {\n    sudoku_board21(string, b);\n    fprintf(stdout,\"%s\", string);\n  }\n\n}\n\nvoid sudoku_get_all_choices(unsigned char *b, char choices&#91;81]&#91;10])\n{\n  int c;\n  \n  for(c = 0; c &lt; 81; c++) {\n    choices&#91;c]&#91;0] = '\\0';\n    if(*(b + c) == ' ') {\n      sudoku_get_choices(b, c, choices&#91;c]);\n    } else {\n      choices&#91;c]&#91;0] = *(b + c);\n      choices&#91;c]&#91;1] = '\\0';\n    }\n  }\n}\n\n\nint sudoku_full(unsigned char b&#91;82])\n{\n  int c;\n  \n  for(c = 0; c &lt; 81; c++) {\n    if(b&#91;c] == ' ')\n      return(0);\n  }\n  return(1);\n}\n\nvoid sudoku_clear(unsigned char b&#91;82])\n{\n  int c;\n\n  for(c = 0; c &lt; 81; c++) {\n    b&#91;c] = ' ';\n  }\n  b&#91;c] = '\\0';\n}\n\nvoid sudoku_cleargrid(unsigned char b&#91;82], unsigned char grid&#91;82], char choice)\n{\n  int c;\n\n  for(c = 0; c &lt; 81; c++) {\n    if(grid&#91;c] == choice)\n      b&#91;c] = ' ';\n  }\n}\n\n\nint sudoku_isallowed(unsigned char b&#91;82], int i, int j, int e)\n{\n  int k, l, base;\n\n  for(k = 0; k &lt; 9; k++) {\n    if(b&#91;i * 9 + k] == e)\n      return(0);\n  }\n  for(k = 0; k &lt; 9; k++) {\n    if(b&#91;9 * k + j] == e)\n      return(0);\n  }\n  base = i \/ 3 * 27 + j \/ 3 * 3;\n  for(k = 0; k &lt; 3; k++) {\n    for(l = 0; l &lt; 3; l++) {\n      if(b&#91;base + k * 9 + l] == e)\n\treturn(0);\n    }\n  }\n  return(1);\n}\n\nint sudoku_verbose = 0;\nint simple_verbose = 0, simple_output = 0, simple_count = 0;\nint solve_verbose = 0;\nint simple_rounds = 0, save_rounds = 0, save_steps = 0, solve_guesses = 0, save_guesses = 0;\nint simple_errors = 0;\nunsigned char newb&#91;82];\n\n#define aDEBUG32 2\n\nint sudoku_simplesolve1(unsigned char b&#91;82])\n{\n  int c, changes = 0;\n  unsigned char choices&#91;10];\n\n  for(c = 0; c &lt; 81; c++) {\n    if(newb&#91;c] == ' ') { \/\/ empty cell\n      choices&#91;0] = '\\0';\n\n      sudoku_get_choices(newb, c, choices);\n\n      int lenchoices = strlen(choices);\n      if(lenchoices == 0) {\n\tbreak;\n      } else if(lenchoices == 1) {\n\tif(simple_verbose) {\n#ifdef DEBUG32\n\t  fprintf(stderr,\"simplesolve1\");\n#endif\n\t  fprintf(stderr,\" %c%c%c\", c \/ 9 + 'A', c % 9 + 'A', *choices);\n#ifdef DEBUG32\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n#endif\n\t}\n\tnewb&#91;c] = *choices;\n\tif(simple_verbose) {\n\t  simple_count++;\n\t  simple_output = 1;\n\t}\n#ifdef DEBUG32\n\tif(simple_verbose) {\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n\t}\n#endif\n\tchanges++;\n      } \/\/ end of if(strlen(choices)\n    } \/\/ end of if(b&#91;c] == ' ') { \/\/ empty cell\n  } \/\/ end of for(c\n\n  return(changes);\n}\n\n#define aDEBUG34 2\n\nint sudoku_simplesolve2(unsigned char b&#91;82]) {\n  int c, i, j, count, cell, changes = 0;\n  \n  for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n    for(i = 0; i &lt; 9; i++) { \/\/ rows\n      count = 0;\n      cell = -1;\n      for(j = 0; j &lt; 9; j++) { \/\/ columns\n\tif(newb&#91;i * 9 + j] == ' ' &amp;&amp;\n\t   sudoku_isallowed(newb, i, j, c) == 1) {\n\t  count++;\n\t  cell = i * 9 + j;\n\t}\n      }\n      if(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\tif(simple_verbose) {\n#ifdef DEBUG34\n\t  fprintf(stderr,\"simplesolve2: rows\");\n#endif\n\t  fprintf(stderr,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n#ifdef DEBUG34\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n#endif\n\t}\n\tnewb&#91;cell] = c;\n\tif(simple_verbose) {\n\t  simple_count++;\n\t  simple_output = 1;\n\t}\n#ifdef DEBUG34\n\tif(simple_verbose) {\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n\t}\n#endif\n\tchanges++;\n\t\/\/sudoku_get_all_choices(b, choices);\n      }\n    }\n  }\n\n  return(changes);\n}\n\n#define aDEBUG36 2\n\nint sudoku_simplesolve3(unsigned char b&#91;82])\n{\n  int c, i, j, count, cell, changes = 0;\n  char choices&#91;81]&#91;10];\n\n  sudoku_get_all_choices(b, choices);\n\n  for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n    for(j = 0; j &lt; 9; j++) { \/\/ columns\n      count = 0;\n      cell = -1;\n      for(i = 0; i &lt; 9; i++) { \/\/ rows\n\tif(newb&#91;i * 9 + j] == ' ' &amp;&amp;\n\t   sudoku_isallowed(newb, i, j, c) == 1) {\n\t  count++;\n\t  cell = i * 9 + j;\n\t}\n      }\n      if(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\tif(simple_verbose) {\n#ifdef DEBUG36\n\t  fprintf(stderr,\"simplesolve3: columns\");\n#endif\n\t  fprintf(stderr,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n\t  simple_output = 1;\n#ifdef DEBUG36\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n#endif\n\t}\n\tnewb&#91;cell] = c;\n\tsimple_count++;\n\n#ifdef DEBUG36\n\tif(simple_verbose) {\n\t  fprintf(stderr,\"\\n\");\n\t  sudoku_print(newb);\n\t}\n#endif\n\tchanges++;\n\t\/\/sudoku_get_all_choices(b, choices);\n      }\n    }\n  }\n\n  return(changes);\n}\n\n#define aDEBUG38 2\n\nint sudoku_simplesolve4(unsigned char b&#91;82])\n{\n  int c, i, j, basei, basej, count, cell, changes = 0;\n  \n  for(basei = 0; basei &lt; 9; basei += 3) {\n    for(basej = 0; basej &lt; 9; basej += 3) {\n      for(c = '1'; c &lt;= '9'; c++) { \/\/ digits\n\tcount = 0;\n\tcell = -1;\n\tfor(i = 0; i &lt; 3; i++) {\n\t  for(j = 0; j &lt; 3; j++) {\n#ifdef KOK\n\t    fprintf(stderr,\"basei:%d\", basei);\n\t    fprintf(stderr,\" basej:%d\", basej);\n\t    fprintf(stderr,\" i:%d\", i);\n\t    fprintf(stderr,\" j:%d\", j);\n\t    fprintf(stderr,\" basei+i:%d\", basei + i);\n\t    fprintf(stderr,\" basej+j:%d\", basej + j);\n\t    fprintf(stderr,\" c:%d\", c);\n\t    fprintf(stderr,\" cell:%d\", cell);\n\t    fprintf(stderr,\"\\n\");\n#endif\n\t    if(newb&#91;(basei + i) * 9 + basej + j] == ' ' &amp;&amp;\n\t       sudoku_isallowed(newb, basei + i, basej + j, c) == 1) {\n\t      cell = (basei + i) * 9 + j + basej;\n\t      count++;\n\t    }\n\t  }\n\t}\n\tif(count == 1 &amp;&amp; cell != -1 &amp;&amp; newb&#91;cell] == ' ') {\n\t  if(simple_verbose) {\n#ifdef DEBUG38\n\t    fprintf(stderr,\"simplesolve4: boxes\");\n#endif\n\t    fprintf(stderr,\" %c%c%c\", cell \/ 9 + 'A', cell % 9 + 'A', c);\n#ifdef DEBUG38\n\t    fprintf(stderr,\"\\n\");\n\t    sudoku_print(newb);\n#endif\n\t  }\n\t  newb&#91;cell] = c;\n\t  \n\t  if(simple_verbose) {\n\t    simple_count++;\n\t    simple_output = 1;\n\t  }\n#ifdef DEBUG38\n\t  if(simple_verbose) {\n\t    fprintf(stderr,\"\\n\");\n\t    sudoku_print(newb);\n\t  }\n#endif\n\t  changes++;\n\t  \/\/sudoku_get_all_choices(b, choices);\n\t} \/\/ end of if(count\n      } \/\/ end of for(c\n    } \/\/ end of for(basej\n  } \/\/ end of for(basei\n\n  return(changes);\n}\n\nint use_simple1 = 1, use_simple2 = 1, use_simple3 = 1, use_simple4 = 1;\n\nint sudoku_simplesolve(unsigned char *b)\n{\n  int changes, changes2 = 0;\n\n  simple_count = 0;\n  simple_rounds = 0;\n  simple_errors = 0;\n  \n  changes = 1;\n  while(simple_errors == 0 &amp;&amp; changes) {\n\n    memcpy(newb, b, sizeof(newb));\n    \n    changes = 0;\n\n    if(use_simple1)\n      changes += sudoku_simplesolve1(b);\n    if(use_simple2)\n      changes += sudoku_simplesolve2(b);\n    if(use_simple3)\n      changes += sudoku_simplesolve3(b);\n    if(use_simple4)\n      changes += sudoku_simplesolve4(b);\n    \n    changes2 += changes;\n    simple_rounds++;\n\n    memcpy(b, newb, sizeof(newb));\n  }\n  if(simple_verbose &amp;&amp; simple_output) {\n    fprintf(stderr,\", moves:%d\\n\", simple_count);\n    simple_output = 0;\n  }\n  return(changes2);\n}\n\nint sudoku_getnextemptycell(char *b, int *i, int *j)\n{\n  int i2, j2;\n  \n  for(i2 = 0; i2 &lt; 9; i2++) {\n    for(j2 = 0; j2 &lt; 9; j2++) {\n      if(*(b + i2 * 9 + j2) == ' ') {\n\t*i = i2;\n\t*j = j2;\n\treturn(1);\n      }\n    }\n  }\n  *i = -1;\n  *j = -1;\n  return(0);\n}\n\nint sudoku_boardsmatch(unsigned char *board, unsigned char *board2)\n{\n  int c, ok;\n\n  ok = 1;\n  for(c = 0;c &lt; 81; c++) {\n    if(*(board + c) != ' ' &amp;&amp;\n       *(board2 + c) != ' ' &amp;&amp;\n       *(board + c) != *(board2 + c)) {\n      ok = 0;\n      break;\n    }\n  }\n  return(ok);\n}\n\nint solve_steps = 0, solve_exact = -1, solve_greater = -1;\nint rounds_greater = -1;\n\nint solve_usesimple = 1;\n\n#define SOLVE_QUICK_EXIT 2 \/\/ on for now\n\n#define aDEBUG57 2\n\nint solve_quick_exit = 1;\nint solve_calculate_steps = 0;\n\nunsigned long long solutions;\n\nunsigned char prevsolution&#91;82];\n\nint sudoku_solve2(unsigned char *sudoku, unsigned char *solution, unsigned long long *solutions)\n{\n  int c, i, j;\n  \n  if(sudoku_getnextemptycell(sudoku, &amp;i, &amp;j) == 0) {\n    (*solutions)++;\n    if(solve_verbose) {\n      if(*solutions % 1000000 == 0) {\n\tFILE *fp1;\n\tif((fp1 = fopen(\"newressusudokusolutions.txt\", \"a\")) != NULL) {\n\t  fprintf(fp1,\"%llu: %s\\n\", *solutions, sudoku);\n\t  fclose(fp1);\n\t}\n      }\n    }\n    if(*solutions == 1)\n      strcpy(solution, sudoku);\n\n#ifdef SOLVE_QUICK_EXIT\n    if(solve_quick_exit &amp;&amp; *solutions &gt; 1) \/\/ quick exit &amp;&amp; multiple solutions, fail\n      return(1);\n    else\n#endif\n      return(0);\n  }\n\n  for(c = '1'; c &lt;= '9'; c++) {\n    if(sudoku_isallowed(sudoku, i, j, c) == 1) {\n      char savesudoku&#91;82];\n      if(solve_usesimple)\n\tstrcpy(savesudoku, sudoku);\n      \n      *(sudoku + i * 9 + j) = c;\n#ifdef DEBUG57\n      if(solve_verbose)\n\tfprintf(stderr,\"%s\\n\", sudoku);\n#endif      \n      if(solve_usesimple)\n\tsudoku_simplesolve(sudoku);\n\n#ifdef OLD1\n      solve_steps++;\n#endif\n\n      if(solve_verbose)\n\tfprintf(stderr,\"%s\",sudoku);\n      solve_guesses++;\n      if(solve_calculate_steps &amp;&amp; sudoku_boardsmatch(sudoku, prevsolution)) {\n\tsolve_steps++;\n\tif(solve_verbose)\n\t  fprintf(stderr,\"*****\");\n      }\n      if(solve_verbose)\n\tfprintf(stderr,\"\\n\");\n\n#ifdef DEBUG57\n      if(solve_verbose)\n\tfprintf(stderr,\"%s\\n\", sudoku);\n#endif\n      if(sudoku_solve2(sudoku, solution, solutions) == 1)\n\treturn(1);\n\n      if(solve_usesimple)\n\tstrcpy(sudoku, savesudoku);\n\n      *(sudoku + i * 9 + j) = ' ';\n    }\n  }      \n  return(0);\n}\n\nint sudoku_solve(unsigned char *sudoku)\n{\n  unsigned char tsudoku&#91;82], solution&#91;82];\n\n  solve_steps = 0;\n  solve_guesses = 0;\n  solutions = 0;\n  if(solve_verbose)\n    fprintf(stderr,\"%s\\n\",prevsolution);\n  memcpy(tsudoku, sudoku, sizeof(tsudoku));\n  sudoku_simplesolve(tsudoku);\n  sudoku_solve2(tsudoku, solution, &amp;solutions);\n  if(solutions == 1) { \/\/ single solution\n    memcpy(sudoku, solution, sizeof(solution));\n    if(solve_verbose) {\n      fprintf(stderr,\"%s\\n\", sudoku);\n    }\n    return(1);\n  }\n  return(0);\n}\n\nunsigned char items&#91;6]&#91;3] = {\n  {  0,1,2 },\n  { 0,2,1 },\n  { 1,0,2 },\n  { 1,2,0 },\n  { 2,0,1 },\n  { 2,1,0 }\n};\n\nvoid sudoku_mix(unsigned char *sudoku)\n{\n  int c, d, e, f, g, h, temp;\n\n  for(c = 0; c &lt; 3; c++) { \/\/ from stacks (bands) 0 - 3\n\n    d = newressu_gen_limit(3); \/\/ to stack (band)) 0 - 3\n    e = newressu_gen_limit(6); \/\/ order of columns (rows) in stack (band)\n\n    for(f = 0; f &lt; 3; f++) { \/\/ order of columns (rows) in from stack (band)\n      g = items&#91;e]&#91;f]; \/\/ order of columns (rows) in stack (band)\n\n      for(h = 0; h &lt; 9; h++) { \/\/ swap columns in stack\n\n\ttemp = *(sudoku + c * 3 + f + h * 9);\n\t*(sudoku + c * 3 + f + h * 9) = *(sudoku + d * 3 + g + h * 9);\n\t*(sudoku + d * 3 + g + h * 9) = temp;\n\n      }\n\n      for(h = 0; h &lt; 9; h++) { \/\/ swap rows in band\n\n\ttemp = *(sudoku + c * 27 + f * 9 + h);\n\t*(sudoku + c * 27 + f * 9 + h) = *(sudoku + d * 27 + g * 9 + h);\n\t*(sudoku + d * 27 + g * 9 + h) = temp;\n\n      }\n    }\n  }\n}\n\nint sudoku_makegrid(unsigned char *b, unsigned char *grid, char choice, unsigned int count)\n{\n  int c, cell, digit;\n  unsigned char choices&#91;10];\n  \n  for(c = 0; c &lt; count; c++) {\n    for(;;) {\n\n       \/\/ get cell number from pseudoressutwist\n      cell = newressu_gen_limit(81);\n\n      if(*(grid + cell) != choice)\n\tcontinue;\n\n      if(*(b + cell) != ' ') \/\/ filled cell\n\tcontinue;\n\n      sudoku_get_choices(b, cell, choices);\n\n      int choiceslen = strlen(choices);\n      if(choiceslen == 0)\n\treturn(1); \/\/ no choices, fail\n      else if(choiceslen == 1)\n\tdigit = choices&#91;0]; \/\/ one choice only, use it\n      else\n\tdigit = choices&#91;newressu_gen_limit(choiceslen)]; \/\/ multiple choices, get digit choise from pseudoressu\n      \n      *(b + cell) = digit;\n      break;\n    } \/\/ end of for(;;)\n  } \/\/ end of for(c = 0; c\n  \n  return(0); \/\/ ok\n}\n\n#define SUDOKU_PHASE2_ROUNDS 30 \/\/ avgtries 2156\n\n#define OUTPUTDB 2\n#define OUTPUTFILE 2\n\n#ifdef OUTPUTDB\n#include \"db8.h\"\n#endif\n\nlong long sumtries = 0, counttries = 0;\nint mode = 0, gmode = 1;\nint mix = 0;\nunsigned char sudokuesfile&#91;128] = \"newressusudokutemp.skk\";\nunsigned char sudokuesdb&#91;128] = \"newressusudoku.skk.db\";\n\nunsigned char sudokuaietana&#91;82] = \"1    7 9  3  2   8  96  5    53  9   1  8   26    4   3      1  4      7  7   3  \";\nunsigned char sudokuhard&#91;82] =     \"     2   7  6  2    9 3   6 7   3 8   3 6   58  1  4   4   7   2  3  5    8 9   1\";\n\nint sudoku_make(unsigned char *b, unsigned char *s, unsigned char *m)\n{\n  int tries = 0, changes = 0, ok;\n  unsigned char board&#91;82], solution&#91;82];\n\n  for(;;) {\n\n    prevsolution&#91;0] = 0;\n    solve_quick_exit = 1;\n    solutions = 0;\n    save_rounds = 0;\n    save_steps = 0;\n    save_guesses = 0;\n\n#define aDEBUG63 2\n  \n#ifdef DEBUG63\n    fprintf(stderr,\".\");\n    sudoku_output = 1;\n    fflush(stderr);\n#endif\n\n    sudoku_clear(board);\n    tries++;\n    \n    if(gmode == 0) {\n      if(tries % SUDOKU_PHASE2_ROUNDS == 0) {\n\tok = 0;\n\twhile(!ok) {\n\t  ok = 1;\n\t  sudoku_clear(board);\n\t  if(sudoku_makegrid(board, sudoku_grid1, '1',  digitsa) == 1)\n\t    ok = 0;\n\t}\n      }\n      if(sudoku_makegrid(board, sudoku_grid1, '2', digitsb) == 1) {\n\tsudoku_cleargrid(board, sudoku_grid1, '2');\n\tcontinue;\n      }\n    } else if(gmode == 1) {\n      ok = 0;\n      while(!ok) {\n\tok = 1;\n\tsudoku_clear(board);\n\tif(sudoku_makegrid(board, sudoku_grid1, '1',  digitsa) == 1)\n\t  ok = 0;\n      }\n    }\n\n    \/\/memcpy(board, sudokuhard, sizeof(sudokuhard));\n    \n    *m = '\\0';\n    if(mix) {\n      strcpy(m, board);\n      sudoku_mix(board);\n    }    \n\n    memcpy(b, board, sizeof(board));\n\n    if(mode == 0) { \/\/ easy\n      sudoku_simplesolve(b);\n      save_rounds = simple_rounds;\n    } else if(mode == 1) { \/\/ hard\n      changes = sudoku_simplesolve(b);\n      save_rounds = simple_rounds;\n      if(changes &gt; 1 &amp;&amp; changes &lt; 10 &amp;&amp; !sudoku_full(b))\n\tsudoku_solve(b);\n      else\n\tcontinue;\n\n    } else if(mode == 2) { \/\/ harder\n      changes = sudoku_simplesolve(b);\n      save_rounds = simple_rounds;\n      if(changes == 1 &amp;&amp; !sudoku_full(b))\n\tsudoku_solve(b);\n      else\n\tcontinue;\n      \n    } else if(mode == 3) { \/\/ hardest\n      if((changes = sudoku_simplesolve(b)) == 0 &amp;&amp;\n\t !sudoku_full(b)) {\n\tsave_rounds = simple_rounds;\n\tsudoku_solve(b);\n      } else\n\tcontinue;\n\n    } else if(mode == 10) { \/\/ solve only\n      solve_quick_exit = 1;\n      sudoku_solve(b);\n      memcpy(prevsolution, b, sizeof(prevsolution));\n    }\n\n    if(solutions &gt; 1)\n      continue;\n    \n    if(!sudoku_full(b))\n      continue;\n\n    if(rounds_greater != -1 &amp;&amp;\n       save_rounds &lt;= rounds_greater)\n      continue;\n\n    if(solve_exact != -1 ||\n       solve_greater != -1) {\n\n      \/\/ calculate solve steps using full\n      \/\/ solve\n      solve_calculate_steps = 1;\n      solve_quick_exit = 0;\n      memcpy(b, board, sizeof(board));\n      sudoku_solve(b);\n      save_steps = solve_steps;\n      save_guesses = solve_guesses;\n\n      if((solve_exact != -1 &amp;&amp;\n\t  solve_exact != solve_steps) ||\n\t (solve_greater != -1 &amp;&amp;\n\t  save_steps &lt;= solve_greater) )\n\tcontinue;\n    }\n\n    memcpy(solution, b, sizeof(solution));\n\n    break;\n  }\n\n  sumtries += tries;\n  counttries++;\n  \n  memcpy(b, board, sizeof(board));\n  memcpy(s, solution, sizeof(solution));\n\n  int digits = 0;\n  unsigned char cboard&#91;82], *p;\n  p = cboard;\n  for(int c = 0; c &lt; sizeof(board); c++) {\n    if(board&#91;c] &gt;= '1' &amp;&amp; board&#91;c] &lt;= '9') {\n      *p++ = board&#91;c];\n      digits++;\n    }\n  }\n  *p = '\\0';\n  \n  int empty = 81 - digits;\n  \n#ifdef OUTPUTDB\n\n  unsigned char temp&#91;16];\n  int templen = 0;\n  static long itemp;\n  static long nextsudokuid;\n\n#ifdef USE_SEMAPHORES\n  my_sem_wait();\n#endif\n  \n  db8_set_filename(sudokuesdb);\n  db8_set_query(\"nextsudokuid\", \"'sudokuid'\");\n\n  nextsudokuid = -1;\n  for(int c = 0;; c++) {\n    if(db8_get_element(\"nextsudokuid\", c, 0, \"sudokuid\", sizeof(temp), &amp;templen, temp)) {\n    } else break;\n    itemp = atol(temp);\n    if(nextsudokuid == itemp)\n      fprintf(stdout,\"Double sudoku %ld == %ld\\n\", nextsudokuid, itemp);\n    if(nextsudokuid &lt; itemp)\n      nextsudokuid = itemp;\n  }\n  nextsudokuid++;\n  db8_clear(\"nextsudokuid\");\n  fprintf(stdout,\"nextsudouid:%ld\\n\",nextsudokuid);\n\n  static int row = 0;\n  \n  db8_set_filename(sudokuesdb);\n  sprintf(temp,\"%ld\", nextsudokuid);\n  nextsudokuid++;\n  db8_put_element(\"sudoku\", row, 0, \"sudokuid\", 0, temp);\n  db8_put_element(\"sudoku\", row, 0, \"board\", 0, b);\n  db8_put_element(\"sudoku\", row, 0, \"solution\", 0, s);\n  db8_put_element(\"sudoku\", row, 0, \"cboard\", 0, cboard);\n  sprintf(temp,\"%d\",digits);\n  db8_put_element(\"sudoku\", row, 0, \"digits\", 0, temp);\n  sprintf(temp,\"%d\",empty);\n  db8_put_element(\"sudoku\", row, 0, \"empty\", 0, temp);\n  if(gmode == 0) {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n    sprintf(temp,\"%d\", digitsb);\n    db8_put_element(\"sudoku\", row, 0, \"digitsb\", 0, temp);\n  } else {\n    sprintf(temp,\"%d\", digitsa);\n    db8_put_element(\"sudoku\", row, 0, \"digitsa\", 0, temp);\n  }\n  sprintf(temp,\"%d\", mode);\n  db8_put_element(\"sudoku\", row, 0, \"mode\", 0, temp);\n  sprintf(temp,\"%d\", gmode);\n  db8_put_element(\"sudoku\", row, 0, \"gmode\", 0, temp);\n  sprintf(temp,\"%d\", save_guesses);\n  db8_put_element(\"sudoku\", row, 0, \"guesses\", 0, temp);\n  sprintf(temp,\"%d\", save_steps);\n  db8_put_element(\"sudoku\", row, 0, \"steps\", 0, temp);\n  sprintf(temp,\"%d\", save_rounds);\n  db8_put_element(\"sudoku\", row, 0, \"rounds\", 0, temp);\n  db8_save(\"sudoku\");\n  db8_clear(\"sudoku\");\n\n  row++;\n\n#ifdef USE_SEMAPHORES\n  my_sem_post();\n#endif\n  \n#endif\n#ifdef OUTPUTFILE\n\n  FILE *fp1;\n  if((fp1 = fopen(sudokuesfile, \"a\"))!=NULL) {\n    *p = '\\0';\n    fprintf(fp1,\"'board' = \\\"%s\\\"\", b);\n    fprintf(fp1,\", 'solution' = \\\"%s\\\"\", s);\n    fprintf(fp1,\", 'cboard' = \\\"%s\\\"\", cboard);\n    fprintf(fp1,\", 'digits' = \\\"%d\\\"\", digits);\n    fprintf(fp1,\", 'empty' = \\\"%d\\\"\", empty);\n    if(gmode == 0) {\n\n      fprintf(fp1,\", 'digitsa' = \\\"%d\\\"\", digitsa);\n      fprintf(fp1,\", 'digitsb' = \\\"%d\\\"\", digitsb);\n    } else if(gmode == 1) {\n      fprintf(fp1,\", 'digitsa' = \\\"%d\\\"\", digitsa);\n    }\n    fprintf(fp1,\", 'mode' = \\\"%d\\\"\", mode);\n    fprintf(fp1,\", 'gmode' = \\\"%d\\\"\", gmode);\n    fprintf(fp1,\"\\n\");\n    fclose(fp1);\n  }\n\n#endif\n\n  return(0);\n}\n\n#include \"more.h\"\n\nint help = 0, quiet = 0, psolution = 0, pboard = 1, avgtries = 0, sudokues = 1;\nint args = 0, history = 0, iquery = 0;\nunsigned char *match = NULL, *query = NULL;\n\nint main(int argc, char *argv&#91;])\n{\n  int c;\n  unsigned char board&#91;82], sboard&#91;82], tboard&#91;82], mixboard&#91;82];\n\n  procname = argv&#91;0];\n\n  sudoku_grid1 = full;\n  \n  \/\/ look thru command line parameters\n  \n  for(c = 1; c &lt; argc; c++) {\n\n    if(!strncmp(\"-\",argv&#91;c], 1)) {\n\n      if(!strcmp(\"--help\", argv&#91;c])) {\n\thelp = 1;\n\n      } else if(!strcmp(\"--args\", argv&#91;c])) {\n\targs = !args;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t\t!strcmp(\"--version\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname);\n\tfprintf(stderr, \", %s\\n\", copyright);\n\texit(0);\n\n      } else if(!strcmp(\"--avgtries\", argv&#91;c])) {\n\tavgtries = !avgtries;\n\t\n      } else if(!strncmp(\"--key\", argv&#91;c], 5)) {\n\tkey = NULL;\n\tif((*argv&#91;c] + 5) != '\\0') {\n\t  key = argv&#91;c] + 5;\n\t} else if(c + 1 &lt; argc) {\n\t  key = argv&#91;c + 1];\n\t  c++;\n\t}\n\tif(key == NULL || strlen(key) &lt; 1) {\n\t  fprintf(stderr,\"%s: not enough key characters \\\"%s\\\"\\n\", procname, argv&#91;c]);\n\t  exit(1);\n\t}\n\n      } else if(!strncmp(\"--sudokues\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  sudokues = atoi(argv&#91;c] + 10);\n\t} else if(c + 1 &lt; argc) {\n\t  sudokues = atoi(argv&#91;c + 1]);\n\t  c++;;\n\t}\n\n      } else if(!strncmp(\"--solution\", argv&#91;c], 10)) {\n\tpsolution = !psolution;\n\n      } else if(!strcmp(\"--board1\", argv&#91;c])) {\n\tboard1 = !board1;\n\n      } else if(!strcmp(\"--board2\", argv&#91;c])) {\n\tboard2 = !board2;\n\n      } else if(!strcmp(\"--board3\", argv&#91;c])) {\n\tboard3 = !board3;\n\n      } else if(!strcmp(\"--board4\", argv&#91;c])) {\n\tboard4 = !board4;\n\n      } else if(!strcmp(\"--board5\", argv&#91;c])) {\n\tboard5 = !board5;\n\n      } else if(!strcmp(\"--board6\", argv&#91;c])) {\n\tboard6 = !board6;\n\n      } else if(!strcmp(\"--board10\", argv&#91;c])) {\n\tboard10 = !board10;\n\n      } else if(!strcmp(\"--board11\", argv&#91;c])) {\n\tboard11 = !board11;\n\n      } else if(!strcmp(\"--board12\", argv&#91;c])) {\n\tboard12 = !board12;\n\n      } else if(!strcmp(\"--board20\", argv&#91;c])) {\n\tboard20 = !board20;\n\n      } else if(!strcmp(\"--board21\", argv&#91;c])) {\n\tboard21 = !board21;\n\n      } else if(!strncmp(\"--history\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  history = atoi(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc &amp;&amp; isdigit(*(argv&#91;c + 1]))) {\n\t  history = atoi(argv&#91;c + 1]);\n\t  c++;\n\t} else \n\t  history = !history;\n\t\n      } else if(!strncmp(\"--match\", argv&#91;c], 7)) {\n\tif(*(argv&#91;c] + 7) != '\\0') {\n\t  match = argv&#91;c] + 7;\n\t} else if(c + 1 &lt; argc) {\n\t  match = argv&#91;c + 1];\n\t  c++;\n\t}\n\n#ifdef OUTPUTDB\n\n      } else if(!strncmp(\"--skkfile\", argv&#91;c], 9)) { \/\/ JariK 2025\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  strcpy(sudokuesdb, argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc) {\n\t  strcpy(sudokuesdb, argv&#91;c + 1]);\n\t  c++;\n\t}\n\t\n      } else if(!strncmp(\"--query\", argv&#91;c], 7)) { \/\/ JariK 2025\n\tquery = NULL;\n\tif(*(argv&#91;c] + 7) != '\\0') {\n\t  query = argv&#91;c] + 7;\n\t} else if(c + 1 &lt; argc &amp;&amp; *(argv&#91;c + 1]) != '-') {\n\t  query = argv&#91;c + 1];\n\t  c++;\n\t}\n\tiquery = 1;\n\n#endif\n\t\n      } else if(!strncmp(\"--more\", argv&#91;c], 6)) { \/\/ JariK 2025\n\tmore = !more;\n\n      } else if(!strncmp(\"--space\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  space = atoi(argv&#91;c] + 7);\n\t} else  if(c + 1 &lt; argc &amp;&amp; isdigit(*(argv&#91;c + 1]))) {\n\t  space = atoi(argv&#91;c + 1] + 7);\n\t  c++;\n\t} else \n\t  space = !space;\n\t\n      } else if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tsudoku_verbose = !sudoku_verbose;\n\t\n      } else if(!strcmp(\"--mix\", argv&#91;c])) {\n\tmix = !mix;\n\t\n      } else if(!strcmp(\"--measy\", argv&#91;c])) {\n\tuse_simple1 = 0;\n\tuse_simple2 = 1;\n\tuse_simple3 = 1;\n\tuse_simple4 = 1;\n\n      } else if(!strcmp(\"--mhard\", argv&#91;c])) {\n\tuse_simple1 = 1;\n\tuse_simple2 = 1;\n\tuse_simple3 = 1;\n\tuse_simple4 = 1;\n\t\n      } else if(!strcmp(\"--simple1\", argv&#91;c])) {\n\tuse_simple1 = !use_simple1;\n\t\n      } else if(!strcmp(\"--simple2\", argv&#91;c])) {\n\tuse_simple2 = !use_simple2;\n\n      } else if(!strcmp(\"--simple3\", argv&#91;c])) {\n\tuse_simple3 = !use_simple3;\n\n      } else if(!strcmp(\"--simple4\", argv&#91;c])) {\n\tuse_simple4 = !use_simple4;\n\n      } else if(!strncmp(\"--digits\", argv&#91;c], 8)) {\n\tif(*(argv&#91;c] + 8) != '\\0') {\n\t  digitsa = atoi(argv&#91;c] + 8);\n\t} else if(c + 1 &lt; argc) {\n\t  digitsa = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tdigitsb = 0;\n\n      } else if(!strncmp(\"--digitsa\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  digitsa = atoi(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc) {\n\t  digitsa = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\n      } else if(!strncmp(\"--digitsb\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0') {\n\t  digitsb = atoi(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc) {\n\t  digitsb = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\t\n      } else if(!strncmp(\"--stepsexact\", argv&#91;c], 12)) {\n\tif(*(argv&#91;c] + 12) != '\\0') {\n\t  solve_exact = atoi(argv&#91;c] + 12);\n\t} else if(c + 1 &lt; argc) {\n\t  solve_exact = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\t\n      } else if(!strncmp(\"--stepsgreater\", argv&#91;c], 14)) {\n\tif(*(argv&#91;c] + 14) != '\\0') {\n\t  solve_greater = atoi(argv&#91;c] + 14);\n\t} else if(c + 1 &lt; argc) {\n\t  solve_greater = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tfprintf(stderr,\"solve_greater:%d\\n\",solve_greater);\n\n      } else if(!strncmp(\"--roundsgreater\", argv&#91;c], 15)) {\n\tif(*(argv&#91;c] + 15) != '\\0') {\n\t  rounds_greater = atoi(argv&#91;c] + 15);\n\t} else if(c + 1 &lt; argc) {\n\t  rounds_greater = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\n      } else if(!strcmp(\"--gmode1\", argv&#91;c]) ) {\n\tgmode = 1;\n\t\n      } else if(!strcmp(\"--gmode0\", argv&#91;c]) ) {\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--mode0\", argv&#91;c]) ) {\n\tmode = 0;\n\t\n      } else if(!strcmp(\"--mode1\", argv&#91;c]) ) {\n\tmode = 1;\n\t\n      } else if(!strcmp(\"--mode2\", argv&#91;c]) ) {\n\tmode = 2;\n\t\n      } else if(!strcmp(\"--mode3\", argv&#91;c]) ) {\n\tmode = 3;\n\t\n      } else if(!strcmp(\"--mode10\", argv&#91;c]) ) {\n\tmode = 10;\n\t\n      } else if(!strcmp(\"--full\", argv&#91;c])) {\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\n      } else if(!strcmp(\"--easy\", argv&#91;c])) {\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy38\", argv&#91;c])) {\n\tdigitsa = 38;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy1\", argv&#91;c])) {\n\tdigitsa = 25;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy2\", argv&#91;c])) {\n\tdigitsa = 27;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy3\", argv&#91;c])) {\n\tdigitsa = 29;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy4\", argv&#91;c])) {\n\tdigitsa = 31;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy38\", argv&#91;c])) {\n\tdigitsa = 38;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy41\", argv&#91;c])) {\n\tdigitsa = 41;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--easy45\", argv&#91;c])) {\n\tdigitsa = 45;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 0; \/\/ easy\n\t\n      } else if(!strcmp(\"--hard\", argv&#91;c])) {\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--hard1\", argv&#91;c])) {\n\tdigitsa = 23;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--hard24\", argv&#91;c])) {\n\tdigitsa = 24;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--hard2\", argv&#91;c])) {\n\tdigitsa = 26;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--hard3\", argv&#91;c])) {\n\tdigitsa = 29;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--hard4\", argv&#91;c])) {\n\tdigitsa = 33;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 1; \/\/ hard\n\t\n      } else if(!strcmp(\"--harder\", argv&#91;c])) {\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 2; \/\/ harder\n\n      } else if(!strcmp(\"--harder1\", argv&#91;c])) {\n\tdigitsa = 23;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 2; \/\/ harder\n\t\n      } else if(!strcmp(\"--harder5\", argv&#91;c])) {\n\tdigitsa = 34;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 2; \/\/ harder\n\t\n      } else if(!strcmp(\"--hardest\", argv&#91;c])) {\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--hardest1\", argv&#91;c])) {\n\tdigitsa = 23;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--hardest2\", argv&#91;c])) {\n\tdigitsa = 27;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--hardest3\", argv&#91;c])) {\n\tdigitsa = 31;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--hardest4\", argv&#91;c])) {\n\tdigitsa = 31;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--hardest5\", argv&#91;c])) {\n\tdigitsa = 33;\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 3; \/\/ hardest\n\t\n      } else if(!strcmp(\"--solve\", argv&#91;c])) {\n\tsudoku_grid1 = full;\n\tgmode = 1;\n\tmode = 10; \/\/ solve\n\t\n      } else if(!strcmp(\"--cross1\", argv&#91;c])) {\n\tdigitsa = 25;\n\tdigitsb = 0;\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--cross2\", argv&#91;c])) {\n\tdigitsa = 30;\n\tdigitsb = 0;\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--cross3\", argv&#91;c])) {\n\tdigitsa = 35;\n\tdigitsb = 0;\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--cross4\", argv&#91;c])) {\n\tdigitsa = 40;\n\tdigitsb = 0;\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--cross5\", argv&#91;c])) {\n\tdigitsa = 45;\n\tdigitsb = 0;\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--cross\", argv&#91;c])) {\n\tsudoku_grid1 = cross;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--plus1\", argv&#91;c])) {\n\tdigitsa = 25;\n\tdigitsb = 10;\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--plus2\", argv&#91;c])) {\n\tdigitsa = 30;\n\tdigitsb = 10;\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--plus3\", argv&#91;c])) {\n\tdigitsa = 35;\n\tdigitsb = 10;\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--plus4\", argv&#91;c])) {\n\tdigitsa = 40;\n\tdigitsb = 10;\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--plus5\", argv&#91;c])) {\n\tdigitsa = 45;\n\tdigitsb = 10;\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--plus\", argv&#91;c])) {\n\tsudoku_grid1 = plus;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--slashes\", argv&#91;c])) {\t\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--slashes1\", argv&#91;c])) {\n\tdigitsa = 23;\n\tdigitsb = 0;\t\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\t\n      } else if(!strcmp(\"--slashes2\", argv&#91;c])) {\n\tdigitsa = 24;\n\tdigitsb = 0;\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--slashes3\", argv&#91;c])) {\n\tdigitsa = 25;\n\tdigitsb = 0;\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--slashes4\", argv&#91;c])) {\n\tdigitsa = 26;\n\tdigitsb = 0;\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--slashes5\", argv&#91;c])) {\n\tdigitsa = 27;\n\tdigitsb = 0;\n\tsudoku_grid1 = slashes;\n\tgmode = 0;\n\n      } else if(!strcmp(\"--test3\", argv&#91;c])) {\n\tuse_simple1 = 1;\n\tuse_simple2 = 1;\n\tdigitsa = 9;\n\tdigitsb = 25;\n\t\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    } \/\/ end of for(c = 1; c &lt; argc; c++)\n    \n  }\n  if(args) {\n    fprintf(stderr,\"argc: %d\\n\", argc);\n    for(c = 0; c &lt; argc; c++) {\n      fprintf(stderr,\"argv&#91;%d]: %s\\n\", c, argv&#91;c]);\n    }\n    exit(1);\n  }\n\n#ifdef OUTPUTDB\n\n  if(iquery == 1) {\n    db8_set_filename(sudokuesdb);\n    if(query != NULL)\n      db8_squery(query);\n    else\n      db8_iquery();\n    exit(0);\n  }\n\n#endif      \n\n  if(help) {\n    fprintf(stderr,\"%s: %s\", procname, procname);\n    fprintf(stderr,\" &#91;--help]\");\n    fprintf(stderr,\" &#91;--copyright]\");\n    fprintf(stderr,\" &#91;--version]\");\n    fprintf(stderr,\" &#91;--board&#91;n]]\");\n    fprintf(stderr,\" &#91;--solution&#91;n]]\");\n    fprintf(stderr,\" &#91;--history&#91;n]\");\n    fprintf(stderr,\"\\n\");\n    exit(1);\n  } \/\/ end of if(help)\n\n  if(!board1 &amp;&amp;\n     !board2 &amp;&amp;\n     !board3 &amp;&amp;\n     !board4 &amp;&amp;\n     !board5 &amp;&amp;\n     !board6 &amp;&amp;\n     !board10 &amp;&amp;\n     !board11 &amp;&amp;\n     !board12 &amp;&amp;\n     !board20 &amp;&amp;\n     !board21) {\n\n   board1 = 1;\n  }\n  \n  if(key != NULL)\n    stream_open(0, key);\n  \n  if(digitsa == -1)\n    digitsa = 27;\n  if(digitsb == -1)\n    digitsb = 10;\n\n  solve_quick_exit = 1;\n  \n#define aDEBUG90 2\n  \n#ifdef DEBUG90\nunsigned char *empty_sudoku =\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \"\n  \"         \";\n#ifdef KOK\n  \"123456789\"\n  \"789123456\"\n  \"456789123\"\n  \"214365897\"\n  \"365897214\"\n  \"897214365\"\n  \"531642978\"\n  \"648971532\"\n  \"972538641\";\n#endif\n \n  fprintf(stderr,\"Counting all solutions...\\n\");\n  fflush(stderr);\n  simple_verbose = 0;\n  solve_quick_exit = 0;\n  solve_verbose = sudoku_verbose;\n  memcpy(tboard, empty_sudoku, sizeof(tboard));\n  sudoku_solve(tboard);\n  fprintf(stderr,\", solutions:%lld\", solutions);\n  sudoku_grid1 = full;\n  simple_verbose = 0;\n  solve_verbose = 0;\n  fprintf(stderr,\", Done\\n\");\n  fflush(stderr);\n#endif\n\n#ifdef OUTPUTDB\n  \n  if(history) {\n    int row, col, first, ok;\n    int namesize, valuesize, namelen, valuelen;\n    unsigned char name&#91;128], value&#91;128];\n\n    namesize = sizeof(name);\n    valuesize = sizeof(value);\n\n    db8_set_filename(sudokuesdb);\n\n    if(match != NULL)\n      db8_set_match(\"sudokues\", match);\n\n    if(more)\n      more_init(); \/\/ adjust thee screensize\n  \n    \n    if(history == 1) {\n\n      db8_verbose = 0;\n      \n      row = 0;\n      \n      for(;;) {\n\n\tok = 0;\n\tif(db8_get_element(\"sudokues\", row, 0, \"board\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\"board:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tif(db8_get_element(\"sudokues\", row, 0, \"solution\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", solution:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tif(db8_get_element(\"sudokues\", row, 0, \"cboard\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", cboard:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tif(db8_get_element(\"sudokues\", row, 0, \"digits\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", digits:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tif(db8_get_element(\"sudokues\", row, 0, \"empty\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", empty:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tif(db8_get_element(\"sudokues\", row, 0, \"digitsa\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", digitsa:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tif(db8_get_element(\"sudokues\", row, 0, \"mode\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", mode:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n      \n\tif(db8_get_element(\"sudokues\", row, 0, \"gmode\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", gmode:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tif(db8_get_element(\"sudokues\", row, 0, \"guesses\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", gmode:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tif(db8_get_element(\"sudokues\", row, 0, \"steps\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", gmode:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tif(db8_get_element(\"sudokues\", row, 0, \"rounds\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", gmode:\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tmore_printf(stdout,\"\\n\");\t\n\n\tif(!ok)\n\t  break;\n\tif(more &amp;&amp; morequit)\n\t  break;\n\trow++;\n      }\n\n    } else if(history == 2) {\n\n      db8_verbose = 0;\n      \n      row = 0;\n    \n      for(;;) {\n\t\n\tfirst = 1;\n\tcol = 0;\n\tok = 0;\n\tfor(;;) {\n\t  if(db8_get_element_num(\"sudokues\", row, col, namesize, &amp;namelen, name, valuesize, &amp;valuelen, value))\n\t    ok = 1;\n\t  else\n\t    break;\n\t  if(!first)\n\t    more_printf(stdout,\", \");\n\t  more_printf(stdout,\"'%s':\\\"%s\\\"\", name, value);\n\t  \n\t  col++;\n\t  first = 0;\n\t}\n\tmore_printf(stdout,\"\\n\");\n\tfflush(stdout);\n\n\tif(!ok)\n\t  break;\n\tif(more &amp;&amp; morequit)\n\t  break;\n\trow++;\n      }\n    } else if(history == 3) {\n\n      db8_verbose = 0;\n      \n      db8_set_query(\"sudokues\", \"'board', 'solution'\");\n\n      row = 0;\n\n      for(;;) {\n\n\tmore_printf(stdout,\"%d \", row);\n\t\n\tfirst = 1;\n\tcol = 0;\n\tok = 0;\n\tfor(;;) {\n\t  \/\/fprintf(stdout,\"row:%d, col:%d, \", row, col);\n\n\t  if(db8_get_element_num(\"sudokues\", row, col, namesize, &amp;namelen, name, valuesize, &amp;valuelen, value))\n\t    ok = 1;\n\t  else\n\t    break;\n\n\t  if(!first)\n\t    more_printf(stdout,\", \");\n\n\t  more_printf(stdout,\"'%s':\\\"%s\\\"\", name, value);\n\t  \n\t  col++;\n\t  first = 0;\n\t}\n\tmore_printf(stdout,\"\\n\");\n\tfflush(stdout);\n\n       \tif(!ok)\n\t  break;\n\tif(more &amp;&amp; morequit)\n\t  break;\n\trow++;\n      }\n    } else if(history == 4) {\n\n      db8_verbose = 0;\n      \n      row = 0;\n      \n      for(;;) {\n\n\tmore_printf(stdout,\"%d \", row);\n\t\n\tok = 0;\n\tif(db8_get_element(\"sudokues\", row, 0, \"board\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\"'board':\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\n\tif(db8_get_element(\"sudokues\", row, 0, \"solution\", valuesize, &amp;valuelen, value)) {\n\t  more_printf(stdout,\", 'solution':\\\"%s\\\"\",value);\n\t  ok = 1;\n\t}\n\t\n\tmore_printf(stdout,\"\\n\");\t\n\n\tif(!ok)\n\t  break;\n\tif(more &amp;&amp; morequit)\n\t  break;\n\n\trow++;\n      }\n\n    }\n    db8_verbose = 0;\n    \/\/db8_dump(\"sudokues\");\n    \/\/db8_clear(\"sudoku\");\n    exit(0);\n  } \/\/ end of if(history\n\n#endif\n  \n#define aDEBUG94 2\n  \n#ifdef DEBUG94\n  \/*\n    A   B   C   D   E   F   G   H   I  \n  +-----------+-----------+-----------+\nA | 1   2     |     9     |         4 |\nB | 4         |         8 |     7     |\nC | 8   3     | 2         |           |\n  +-----------+-----------+-----------+\nD | 6         |     2     |           |\nE | 2         | 1   6     | 4   3   5 |\nF |           |           | 7         |\n  +-----------+-----------+-----------+\nG |           |     8     | 2   4     |\nH |           |           | 5       3 |\nI |           |     4     |           |\n  +-----------+-----------+-----------+\n  s:0 steps:512 rounds:0 digits:25\n  *\/\n  unsigned char hard1&#91;82] =\n    \"12  9   4\"\n    \"4    8 7 \"\n    \"83 2     \"\n    \"6   2    \"\n    \"2  16 435\"\n    \"      7  \"\n    \"    8 24 \"\n    \"      5 3\"\n    \"    4    \";\n  unsigned char solution&#91;82];\n\n  sudoku_clear(solution);\n  memcpy(board, sudokuaietana, sizeof(sudokuaietana));\n  sudoku_print(board);\n\n  simple_verbose = 1;\n  memcpy(tboard, board, sizeof(board));\n  sudoku_simplesolve(tboard);\n  sudoku_print(tboard);\n\n  simple_verbose = 0;\n  solve_verbose = 1;\n  memcpy(tboard, board, sizeof(board)); \n  solve_quick_exit = 0;\n  solve_usesimple = 1;\n  sudoku_solve(tboard);\n  if(solutions &gt; 1)\n    fprintf(stderr,\"multiple solutions\\n\");\n  fprintf(stderr,\"solvesteps:%d\\n\", solve_steps);\n  sudoku_print(tboard, 1);\n  fprintf(stderr,\"**********\\n\");\n\n#endif\n\n#ifdef USE_SEMAPHORES\n  my_sem_open();\n#endif\n  \n  unsigned char simplesolution&#91;82], solvesolution&#91;82];\n  unsigned char solvesolutions&#91;82];\n  int id = 0;\n  \n  for(int boards = 0; boards &lt; sudokues; boards++) {\n\n    solve_usesimple = 1;\n\n    solve_quick_exit = 1;\n    \n    simple_verbose = 0;\n    solve_verbose = 0;\n    sudoku_clear(board);\n    sudoku_clear(sboard);\n    sudoku_make(board, sboard, mixboard);\n\n    if(sudoku_output) {\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n      sudoku_output = 0;\n    }\n\n    \/\/ simplesolve for verbose\n    \n    memcpy(tboard, board, sizeof(board));\n    simple_verbose = sudoku_verbose;\n    sudoku_simplesolve(tboard);\n    memcpy(simplesolution, tboard, sizeof(simplesolution));\n    save_rounds = simple_rounds;\n    simple_verbose = 1; \/\/ *****\n\n    \/\/ solve for verbose\n    \n    memcpy(tboard, board, sizeof(board));\n    solve_verbose = sudoku_verbose;\n    solve_usesimple = 1;\n    solve_quick_exit = 0;\n    simple_verbose = 0;\n    sudoku_solve(tboard);\n    memcpy(solvesolution, tboard, sizeof(solvesolution));\n    save_steps = solve_steps;\n    save_guesses = solve_guesses;\n    solve_verbose = sudoku_verbose;\n\n    \/\/ solve without usesimple\n    \n    solve_usesimple = 0;\n    simple_verbose = 0;\n\n    sudoku_solve(tboard);\n    memcpy(solvesolutions, tboard, sizeof(solvesolution));\n    \n    if(mix &amp;&amp; sudoku_verbose)\n      sudoku_print(mixboard);\n    \n    sudoku_print(board);\n\n    int digits = 0;\n    for(c = 0;c &lt; sizeof(board); c++)\n      if(board&#91;c] &gt;= '0' &amp;&amp; board&#91;c] &lt;= '9')\n\tdigits++;\n    \n    fprintf(stdout,\"  s:%d\", id);\n    fprintf(stdout,\" gu:%d\", save_guesses);\n#ifdef SOLVE_QUICK_EXIT\n    fprintf(stdout,\" st:%d\", save_steps);\n#endif\n    fprintf(stdout,\" ro:%d\", save_rounds);\n    fprintf(stdout,\" clues:%d\", digits);\n    fprintf(stdout,\"\\n\");\n\n    if(psolution) {\n      sudoku_print(solvesolution);\n      fprintf(stdout,\"  s:%d\", id);\n      fprintf(stdout,\"\\n\");\n    }\n    fflush(stdout);\n    id++;\n\n    if(space) {\n      if(space == 1)\n\tfprintf(stdout,\"\\n\");\n      else if(id % space != 0)\n\tfprintf(stdout,\"\\n\");\n    }\n    \n    \/\/if(sudoku_verbose) {\n    \n    solve_verbose = sudoku_verbose;\n    \n    if(sudoku_boardsmatch(board, simplesolution) &amp;&amp;\n       sudoku_boardsmatch(board, solvesolution) &amp;&amp;\n\n       sudoku_boardsmatch(board, solvesolutions) &amp;&amp;\n\n       sudoku_boardsmatch(simplesolution, solvesolution) &amp;&amp;\n       sudoku_full(solvesolution)) {\n    } else {\n      fprintf(stderr,\"board:    %s\\n\", board);\n      fprintf(stderr,\"simple:   %s\\n\", simplesolution);\n\n      fprintf(stderr,\"solvewsi: %s\\n\", solvesolutions);\n\n      fprintf(stderr,\"solve:    %s\\n\", solvesolution);\n      fprintf(stderr,\"board and solutions differ\\n\");\n    }\n\n    if(sudoku_verbose)\n      fprintf(stderr,\"solvesteps:%d\\n\", save_steps);\n    fflush(stdout);\n  }\n\n#ifdef USE_SEMAPHORES\n  my_sem_close();\n#endif\n  \n  if(avgtries)\n    fprintf(stderr,\"avgtries:%f\\n\",(double) sumtries \/ counttries);\n  return(0);\n}<\/code><\/pre>\n\n\n\n<p>Suurin osa t\u00e4st\u00e4 postista on ollut exfat debukkailua ja satunnaisuus testiajoja, mutta taas kerran tuntuu silt\u00e4 ett\u00e4 &#8220;pasianssi&#8221; menee l\u00e4pi. Eli ett\u00e4 nuo db_get ja db_put rutiinit toimivat tosiaan sovelluksen koodauksessa. T\u00e4ll\u00e4 hetkell\u00e4 mieless\u00e4ni on idea ett\u00e4 sovellukseen tarvittavat kyselyt ja rivit nimet\u00e4\u00e4n sovelluksen &#8220;sis\u00e4isill\u00e4&#8221; nimill\u00e4 (header,  lines, headerfields, linesfields, session, log jne&#8230;) ja niille lis\u00e4t\u00e4\u00e4n j\u00e4rjestysnumero. J\u00e4rjestysnumerolla voidaan lukea useampirivisen kyselyn halutun rivin kentt\u00e4. Esimerkiksi tilausrivit, taulukon sarakkeiden nimet, otsakkeen kenttien nimet. Onkohan jo aika \ud83c\udf7e&amp;\ud83e\udd42, aika n\u00e4ytt\u00e4\u00e4&#8230;<\/p>\n\n\n\n<p>Jos kokeilet loppukevennyksen sudokuohjelmalla sudokujen etsimist\u00e4, voisit tehd\u00e4 palveluksen ja j\u00e4tt\u00e4\u00e4 l\u00f6yt\u00e4m\u00e4si vaikeat sudokut, joissa steps on suurempi tai yht\u00e4suurikun 12, kommentteihin (Edelliset kolme steps:12 sudokua ovat ainoat l\u00f6yt\u00e4m\u00e4ni). Toisaalta jos pid\u00e4t ohjelman laatimista sudokuista niin j\u00e4t\u00e4 kommentti tai jos haluat, tee lahjoitus. <\/p>\n\n\n\n<p>Olen miettinyt, ett\u00e4 t\u00e4st\u00e4 saattaisi olla mahdollista tehd\u00e4 viel\u00e4 yksi uusi ammatti (\/ansaintatapa), ja kyselenkin, koetteko saavanne n\u00e4iden artikkeleiden lukemisesta niin paljon arvoa ett\u00e4 voitte tukea niit\u00e4.<\/p>\n\n\n\n<p>Lahjoituksen suomessa voi tehd\u00e4, mutta ei voi sit\u00e4 pyyt\u00e4\u00e4.Yrit\u00e4n keksi\u00e4 lahjoitukselle jonkin vastalahjan. Lahjoitus kattaa t\u00e4m\u00e4n ja edellisten artikkeleiden viihdearvon. Arvon, jota ajattelen raporttien voivan antaa ovat tietysti henkil\u00f6kohtaisia. P\u00e4\u00e4llisimp\u00e4n\u00e4 ajattelen viihdearvoa, seuraavina uutuusarvo, k\u00e4ytt\u00f6arvo, julkistusarvo jne\u2026 Toisaalta joku voi ajatella t\u00e4m\u00e4n arvoa hyv\u00e4n\u00e4 hack:in\u00e4 (vanha merkitys, nykyinen termi ~eettinen hack).<\/p>\n\n\n\n<p>old: Ensimm\u00e4inen vastalahjavaihtoehto on muistitikku tai dvd-levy, jolla on l\u00e4hdekoodeja. Lahjoitussumman ajattelin korvaavan levyjen valmistuksen kopiointikulut. Toinen vaihtoehto on tietysti mietti\u00e4 summaa, joka mahdollistaisi koodaamisen ja ei veisi koodaamiselta liiaksi aikaa. Toisaalta vastalahjalla pit\u00e4isi olla muutakin arvoa kun ohjelmistot, ehk\u00e4p\u00e4 joku &#8220;laatutikku&#8221;, tai toisaalta mahdollinen dvd-levyn &#8220;taiteellinen&#8221; etiketti. Lahjoitus voisi voisi olla 1000\u20ac. Ensimm\u00e4isen valmistuksessa aina tietenkin kest\u00e4\u00e4&#8230; Vastalahjatikku on edistynyt sen verran ett\u00e4 sis\u00e4lt\u00f6 on vaatimaton edistymisraportti, joka sis\u00e4lt\u00e4\u00e4 artikkelin l\u00e4hdekoodeja ja niiden varmuuskopioita artikkelin kirjoituksen ajalta. Hakusessa on viel\u00e4 saisiko artikkelin pdf:n mukaan tikulle.<\/p>\n\n\n\n<p>old: Toinen vastalahjavaihtoehto on nippu loppukevennyksen uniikkeja sudokuja. Suuremmasta lahjoituksesta voin askarrella yhden numeroitun, leimatun, muovitetun sudokun. T\u00e4m\u00e4n voin toteuttaa jo nyt. (katso artikkelin alku)<\/p>\n\n\n\n<p>Viel\u00e4 joukko entist\u00e4kin parempia satunnaislukuja newressulla (+ 2 korjaus, copy\/reverse muutos ja &#8220;bad for randomness&#8221; -korjaus):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu\n00000 77458582497443145904566934443436246480701130620326935991456610973\n00001 94507419393879258178180749627076833108928192114356128593175144808\n00002 69955332005176379096756541035011728926172026506046261674970499492\n00003 10041144250791764746028281923017387934850354308811311475334133566\n00004 35481673992214936870774513280004290499190496268994268401165338970\n00005 82463289343086188404499348759211815912057510425970342155995679459\n00006 57920773023068190680028846995762779195455248238525716464305873857\n00007 86630133084381732337741142532649045059766988279545483298107240233\n00008 01015986958233860186920327673324049941187364720513073490914507087\n00009 28508727880161886875910325608456711423282083816715925889000039535\n$<\/code><\/pre>\n\n\n\n<p>Viel\u00e4 ressun ja pseudoressu:n yhdistelm\u00e4 ressutwist: t\u00e4m\u00e4n pit\u00e4isi olla kest\u00e4v\u00e4mpi kun pelkk\u00e4 ressu. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --ressutwist\n00000 38169523754911197205187055060318737263295581333071814524589708402\n00001 72357785313131012189080233848055894425568528104200838183302063376\n00002 46313582383678766598338369217460575659675989837848215915983938840\n00003 42087445607719393940612257351025832890546631293746186346013303374\n00004 12111436258786575204528802582398706615613192232411446341863086139\n00005 72046192140160144744229764463489240213143808100563106362594903710\n00006 69877913434074772919675327159017485427086810711562559812792448662\n00007 32295749372024209206376009222244012624606168682788316244901158666\n00008 63384464324225511781931177910571924012544413758040773312731575605\n00009 58904257885745995006916810801142432472067950180960633658250684053\n$ <\/code><\/pre>\n\n\n\n<p>Ja viel\u00e4 satunnaisbittej\u00e4 copy-reversen uusimmalla versiolla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu\n00000 07335951055253046500024163620453813836373328157321739152165317232\n00001 40437299179549477553339146701997626827264050286975274380764359537\n00002 75949993077782013732124213539976675604773074469960950132152302275\n00003 05898243685309528542470891406823291120178413018559965061316979463\n00004 48592522524365791666828231469872960396694950351782368719254710405\n00005 44605804163182092800496364780633986485900223135483144357756924456\n00006 49967812285265296249341492424239573141753602165258479636833398129\n00007 63349903954970474474841131104375788104580100307465955328736696190\n00008 00759242770205026105719795721070351377102239463323928394740626089\n00009 53518248667093503967427116311430118211771697290836792208148299677\n$ <\/code><\/pre>\n\n\n\n<p>Sitten newressu sorsa kokonaisuudessaan, ensin Makefile:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CC =\t\tcc\nCFLAGS =\t-g -Wall -Wno-pointer-sign\nnewressuobjs =\tnewressu.mfs.o fort.o sha256.o intelrandom.o webrandom.o commandrandom.o\nnewressusudokuobjs = newressusudoku.o more.o newressu.s.o sha256.o db8.q.o\ndb8objs = db8.mq.o more.o\nsha256objs =\tsha256.m.o\n\nall:\t\tprogs tests\n\nprogs:\t\tnewressu\n\nnewressu:\t$(newressuobjs)\n\t\tcc $(CFLAGS) $(newressuobjs) -o newressu -lssl -lcrypto -lm\n\nnewressusudoku:\t$(newressusudokuobjs)\n\t\tcc $(CFLAGS) -pthread -DSHA256 $(newressusudokuobjs) -o newressusudoku -lm\n\ndb8:\t\t$(db8objs)\n\t\tcc $(CFLAGS) -DSHA256 $(db8objs) -o db8 -lm\n\nsha256:\t\t$(sha256objs)\n\t\tcc $(CFLAGS) $(sha256objs) -o sha256\n\n%.mfs.o:\t%.c\n\t\t$(CC) $(CFLAGS) -DMAIN -DFORT -DSHA256 -c -o $@ $&lt;\n\n%.fs.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DFORT -DSHA256 -c -o $@ $&lt;\n\n%.m.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DMAIN -c -o $@ $&lt;\n\n%.p.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DPSEUDORESSU -c -o $@ $&lt;\n\n%.s.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DSHA256 -c -o $@ $&lt;\n\n%.s.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DSHA256 -c -o $@ $&lt;\n\n%.q.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DQUERY -c -o $@ $&lt;\n\n%.mq.o:\t\t%.c\n\t\t$(CC) $(CFLAGS) -DMAIN -DQUERY -c -o $@ $&lt;\n\nclean:\n\t\trm -f *~ \\#*\\# *.o disk\/*\n\ninstall:\tnewressu\n\t\tcp newressu \/bin\/newressu\n\t\tcp newressusudoku \/bin\/newressusudoku\n<\/code><\/pre>\n\n\n\n<p>newressu.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;time.h>\n#include &lt;ctype.h>\n#include &lt;sys\/time.h>\n#include &lt;math.h>\n#include &lt;sys\/types.h>\n\n\/\/#define SHA256 2 \/\/ in Makefile\n\n#include \"sha256.h\"\n\n\/\/#define MAIN 2 \/\/ in Makefile\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"Newressu version 4.10 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 1998-2024 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\nint newressu_output = 0;\n\nvoid ressu_dump(unsigned char *header, int len, unsigned char *buf, int linelen)\n{\n  int c;\n\n  if(newressu_output) {\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  for(c = 0; c &lt; len; c++) {\n    if(c % linelen == 0) {\n      if(c > 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%-10s\", header);\n    }\n    fprintf(stdout,\" %02x\", buf&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n}\n\nstatic unsigned long periods&#91;1024];\nstatic unsigned long genbytes = 0;\nstatic unsigned long clockbytes = 0;\n\nint verbose = 0;\nint size = -1, type = 10;\n\n#define USE_RANDOM 2\n\n#define ALL_SLICE 16 \/\/ 16 \/\/ orig 64\n#define RESSUT_SLICES 128 \/\/ 128 \/\/ orig 32\n#define RESSUT_BYTES (RESSUT_SLICES * ALL_SLICE) \/\/ 2048 16 * 128 \/\/ (32 * 64)\n\n#define RESSU_MIN_ROUNDS 2\n#define RESSU_MIN_CLOCKBYTES 16 * 1024\n\n#define GENT_SLICES 128 \/\/ 32 \/\/ orig 16\n#define GENT_SIZE (GENT_SLICES * ALL_SLICE) \/\/ 1024 (16 * 64)\n\nstatic int ressut_bytes = (RESSUT_SLICES * ALL_SLICE); \/\/ orig 2048\nstatic int ressut_bits1_needed = RESSUT_SLICES * 2; \/\/ orig 256\nstatic int ressut_bits2_needed = RESSUT_SLICES * 8; \/\/ orig 1024\nstatic int ressut_bits3_needed = RESSUT_SLICES * 16; \/\/ orig 2048\nstatic int ressut_bits4_needed = RESSUT_SLICES * 16; \/\/ orig 2048\nstatic int ressut_bits5_needed = RESSUT_SLICES * 16; \/\/ orig 2048\nstatic int ressut_bits6_needed = RESSUT_SLICES * 32; \/\/ orig 2048 * 2\nstatic int ressut_bits7_needed = RESSUT_SLICES * 128; \/\/ orig 2048 * 8\nstatic int ressut_bits20_needed = RESSUT_SLICES * 32; \/\/ orig 2048 * 2\nstatic int ressut_bits21_needed = RESSUT_SLICES * 16; \/\/ orig 2048\n\nint rndbits1 = 0,\n  rndbits2 = 0,\n  rndbits3 = 0,\n  rndbits4 = 0,\n  rndbits5 = 0,\n  rndbits6 = 0,\n  rndbits7 = 0,\n  rndbits20 = 0,\n  rndbits21 = 0,\n  rndbits22 = 0;\n\nstatic int stats = 0;\n\n#define DEBUG_SORTED 2\n\nunsigned long long ressu_useconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec + 1000000 * tv.tv_sec);\n}\n\nstatic unsigned char ressu_lowusec() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}\n\n#define FIXEDCLOCKCHAINLENGTH 50 \/\/ orig 50\nunsigned int fixedclockchainlength = FIXEDCLOCKCHAINLENGTH;\n\nint fixedclock = 0; \/\/ 0 = normal, 1 = fixed\n\nstatic unsigned char ressu_clock()\n{\n  static unsigned int clockbyte = 0, counter = 0;\n\n  if(!fixedclock)\n    return ressu_lowusec();\n  else {\n    if(counter == 0) {\n      clockbyte++;\n      counter += fixedclockchainlength;\n    }\n    counter--;\n    return(clockbyte &amp; 0xff);\n  }\n}\n\n#include &lt;sys\/types.h>\n#include &lt;unistd.h>\n\n#define aDEBUG2A 2\n#define aDEBUG2B 2\n#define aDEBUG2C 2\n#define aDEBUG2D 2\n#define aDEBUG2E 2\n#define aDEBUG2F 2\n#define aDEBUG2G 2\n#define aDEBUG2H 2\n\nstatic unsigned char *ressuct; \/\/ ressu random buffer lookup\nstatic unsigned int ressuct_bytes;\nstatic unsigned char ch;\n\n#ifdef DEBUG2H\n\nunsigned long count&#91;RESSUT_BYTES];\n\n#endif\n\nstatic unsigned int ressu_nonrandom() \/\/ not really random\n{\n  static unsigned int rando = 0;\n  struct timeval tv;\n\n  int pid = getpid();\n  int clock2 = clock();\n  gettimeofday(&amp;tv, NULL);\n\n#ifdef DEBUG2G\n\n  static int rowid = 0;\n\n  if(rowid == 0) {\n    fprintf(stdout,\"%6s\",\"rowid\");\n    fprintf(stdout,\"%6s\",\"rando\");\n    fprintf(stdout,\"%6s\",\"pid\");\n    fprintf(stdout,\"%6s\",\"clk\");\n    fprintf(stdout,\"%6s\",\"dtime\");\n    fprintf(stdout,\"%6s\",\"+usec\");\n    fprintf(stdout,\"%6s\",\"ptime\");\n    fprintf(stdout,\"%6s\",\"+usec\");\n    fprintf(stdout,\"%6s\",\"ch*ch\");\n    fprintf(stdout,\"%6s\",\"newra\");\n    fprintf(stdout,\"\\n\");\n  }\n  fprintf(stdout,\"%6d\", rowid++);\n  fprintf(stdout,\"%6d\", rando % RESSUT_BYTES);\n\n#endif\n  \n  rando = rando +\n    \/\/genbytes +\n    \/\/time(NULL) +\n    \/\/ressu_useconds() +\n    \/\/ressu_clock() +\n    \/\/buf.tms_utime + \n    \/\/buf.tms_stime +\n    pid +\n    clockbytes +\n    tv.tv_sec +\n    tv.tv_usec +\n    clock2 \/ CLOCKS_PER_SEC +\n    clock2 % CLOCKS_PER_SEC +\n    ch * ch;\n\n#ifdef DEBUG2G\n  \n  fprintf(stdout,\"%6d\", pid % RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", (int) clockbytes %RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", (int) tv.tv_sec % RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", (int) tv.tv_usec % RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", (int) (clock2 \/ CLOCKS_PER_SEC) % RESSUT_BYTES); \n  fprintf(stdout,\"%6d\", (int) (clock2 % CLOCKS_PER_SEC) % RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", (int) (ch * ch) % RESSUT_BYTES);\n  fprintf(stdout,\"%6d\", rando % RESSUT_BYTES);\n  fprintf(stdout,\"\\n\");\n\n#endif\n  \n#ifdef DEBUG2H\n  count&#91;rando % ressuct_bytes]++;\n#endif\n  \n#if defined DEBUG2C &amp;&amp; !defined DEBUG2G\n  static unsigned int itemnum = 0;\n  \n  if(itemnum % 16 == 0) {\n    if(itemnum > 0)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%05d \", itemnum);\n  }\n  fprintf(stdout,\" %4u\", rando % ressuct_bytes);\n  itemnum++;\n  newressu_output = 1;\n#endif\n\n  return(rando);\n}\n\n#define MAX_DEPTH 4 \/\/ now 4\n\nint depth = 4; \/\/ now 4\n\nunsigned int copyreverse = 1;\nunsigned long cblocks = 0;\nunsigned char lens = 4;\n\nstatic unsigned char ressu_copyreverse(int pdepth) \/\/ 2024 JariK\n{\n  static int reverse&#91;MAX_DEPTH] = {0}; \/\/ 0 = copy, 1 = reverse, 28.10.2022 JariK\n  static unsigned int len&#91;MAX_DEPTH] = {0};\n  static unsigned int count&#91;MAX_DEPTH] = {0};\n  static unsigned int low&#91;MAX_DEPTH] = {0};\n  static unsigned int high&#91;MAX_DEPTH] = {0};\n  static unsigned char bytes&#91;MAX_DEPTH]&#91;257] = {0};\n  \n  if(pdepth == 0) {\n#ifdef DEBUG2D\n    int c = ressu_clock();\n    \/\/fprintf(stdout,\", ch2:%02x\",c);\n    return(c);\n#else\n    return(ressu_clock());\n#endif\n  }\n\n  pdepth--;\n\n  \/\/ dividing clock stream into blocks\n  \/\/ and reversing every other block\n\n  \/\/ copy next block to bytes\n  \n  if(count&#91;pdepth] == 0) { \/\/ previous block ended\n    reverse&#91;pdepth] = !reverse&#91;pdepth];\n    len&#91;pdepth] = ressuct&#91;ressu_nonrandom() % ressuct_bytes] + 2; \/\/ block size\n    \/\/len&#91;pdepth] = (ressuct&#91;ressu_nonrandom() % ressuct_bytes] &amp; 3 ) + 2; \/\/ block size\n    \/\/len&#91;pdepth] = --lens + 2; \/\/ block size\n    \/\/len&#91;pdepth] = lens++ + 2; \/\/ block size\n    count&#91;pdepth] = len&#91;pdepth];\n    low&#91;pdepth] = 0;\n    high&#91;pdepth] = len&#91;pdepth];\n    rndbits2 += 2;\n#ifdef DEBUG2A\n    fprintf(stdout,\"\\nblk:\");\n    fprintf(stdout,\" depth:%d\", pdepth);\n    fprintf(stdout,\", reverse:%d\", reverse&#91;pdepth]);\n    fprintf(stdout,\", len:%d\", len&#91;pdepth]);\n    fprintf(stdout,\", count:%d\", count&#91;pdepth]);\n    fprintf(stdout,\", low:%d\", low&#91;pdepth]);\n    fprintf(stdout,\", high:%d\", high&#91;pdepth]);\n    fflush(stdout);\n#endif\n    for(int c = 0; c &lt; len&#91;pdepth]; c++) {\n      bytes&#91;pdepth]&#91;c] = ressu_copyreverse(pdepth); \/\/ block bytes\n#ifdef DEBUG2A\n      fprintf(stdout,\", b%d:%02x\", pdepth, bytes&#91;pdepth]&#91;c]);\n      newressu_output = 1;\n#endif\n    }\n  }\n  if(reverse&#91;pdepth]) { \/\/ reverse\n    \n    \/\/ get reversed byte to return\n    ch = bytes&#91;pdepth]&#91;--high&#91;pdepth]]; \/\/ reverse\n#ifdef DEBUG2E\n    fprintf(stdout,\", rev%d:%02x\", pdepth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;pdepth];\n\n  } else { \/\/ copy\n    \n    \/\/ get copied byte to return\n    ch = bytes&#91;pdepth]&#91;low&#91;pdepth]++]; \/\/ copy\n#ifdef DEBUG2E\n    fprintf(stdout,\", copy%d:%02x\", pdepth, ch);\n    fflush(stdout);\n#endif\n    --count&#91;pdepth];\n  }\n\n  return(ch);\n}\n\nstatic unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  if(copyreverse) {\n    ch = ressu_copyreverse(depth);\n  } else {\n    ch = ressu_clock();\n  } \/\/ end of if(copyreverse)\n\n#ifdef DEBUG2F\n  static unsigned int cols = 0;\n  if(cols % 32 == 0) {\n    if(cols > 0)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"%05u \",cols);\n    newressu_output = 1;\n  }\n  if(cols % 4 == 0)\n    fprintf(stdout,\" \");\n  fprintf(stdout,\"%02x\",ch);\n  newressu_output = 1;\n  cols++;\n#endif\n  \n  \/\/ statistics for theoretical\n  \/\/ random bits calculation (rndbits?)\n  \n  static int prevbyte = -1, clockcount = 0;\n  \n  if(prevbyte == -1)\n    prevbyte = ch;\n  if(prevbyte != ch) {\n    periods&#91;clockcount]++;\n    clockbytes += clockcount;\n#ifdef DEBUG2B\n    fprintf(stdout,\" %d\", clockcount);\n    newressu_output = 1;\n#endif\n    if((ch &amp; 1) != (prevbyte &amp; 1))\n      rndbits20++;\n    if((ch &amp; 2) != (prevbyte &amp; 2))\n      rndbits21++;\n    if((ch &amp; 4) != (prevbyte &amp; 4))\n      rndbits22++;\n    clockcount = 0;\n    prevbyte = ch;\n  }\n  clockcount++;\n  \n  return(ch);\n}\n\n#define RR8(byte, bits) ( ((byte) >> (bits)) | ((byte) &lt;&lt; (8 - (bits))) )\n#define RL8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) &lt;&lt; (bits)) )\n\n#define aDEBUG5A 2\n#define aDEBUG5B 2\n#define aDEBUG5C 2\n#define aLOWCLOCKBITONLY 2 \/\/ off by default\n\nvoid ressu_genbytes_single_do(int size, unsigned char *buffer) \/\/ JariK 2013\n{\n  int c, d;\n  unsigned char e;\n  static int f = 0;\n  \n  for(c = 0; c &lt; 8; c++) {\n    for(d = 0; d &lt; size; d++) { \/\/ shift and xor\n      e = buffer&#91;d];\n      e = RL8(e, 1); \/\/ rotate byte left 1 bits\n      \/\/e = RL8(e, 3); \/\/ rotate byte left 3 bits\n      \/\/e = RR8(e, 1); \/\/ rotate byte right 1 bits\n\n#ifdef LOWCLOCKBITONLY\n      buffer&#91;d] = e ^ (ressu_clockbyte() &amp; 1);\n#else\n      buffer&#91;d] = e ^ ressu_clockbyte();\n#endif\n    }\n#ifdef DEBUG5A\n    if(newressu_output)\n      fprintf(stdout, \"\\n\");\n    ressu_dump(\"ressu 1\", 32, buffer, 32);  \/\/ first 32 bytes\n    fflush(stdout);\n#endif\n    for(d = 0; d &lt; size; d++) { \/\/ swap\n#ifdef DEBUG5B\n      fprintf(stdout,\"d:%d\", d);\n      fprintf(stdout,\", f:%d\", f);\n      fprintf(stdout,\", bufferd:%d\", buffer&#91;d]);\n      fprintf(stdout,\", bufferf:%d\", buffer&#91;f]);\n      fprintf(stdout,\"\\n\");\n#endif\n      f = (f + buffer&#91;d] + 2) % size; \/\/ + 2 JariK 2022\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n#ifdef DEBUG5A\n    if(newressu_output)\n      fprintf(stdout,\"\\n\");\n    ressu_dump(\"ressu 2\", 32, buffer, 32); \/\/ first 32 bytes\n    fflush(stdout);\n#endif\n#ifdef DEBUG5C\n    fprintf(stdout,\"\\n\");\n    ressu_dump(\"ressu 3\", size, buffer, 32); \/\/ whole buffer\n    fflush(stdout);\n#endif\n  }\n}\n\nvoid ressu_genbytes_single(int size, unsigned char *buffer)\n{\n  ressuct = buffer;  \/\/ ressu random buffer lookup\n  ressuct_bytes = size;\n\n  rndbits2 = 0;\n  clockbytes = 0;\n\n  cblocks = 0;\n\n  ressu_genbytes_single_do(size, buffer);\n\n  \/\/\n  \/\/  display statistics\n  \/\/\n\n  if(stats) {\n\n    if(newressu_output == 1)\n      fprintf(stdout, \"\\n\");\n    newressu_output = 0;\n\n    fprintf(stderr, \"rounds:1\");\n\n    long chains = 0;\n    \n    for(int e = 0; e &lt; 1024; e++) {\n      if(periods&#91;e] > 0) {\n\tfprintf(stderr, \" %d:%lu\", e, periods&#91;e]);\n\tchains += periods&#91;e];\n      }\n    }\n    \n    fprintf(stderr, \", chains:%ld\", chains);\n    fprintf(stderr, \", blocks:%ld\", cblocks);\n    fprintf(stderr, \", clockbytes:%ld\", clockbytes);\n    fprintf(stderr, \", rndbits2:%d\", rndbits2);\n    fprintf(stderr, \"\\n\");\n    fflush(stderr);\n  }\n#ifdef DEBUG7\n\n  ressu_dump(\"single\", size, buffer, 32);\n\n#endif\n  \n  genbytes += size;\n}\n\nvoid ressu_genbytes_fast(int size, unsigned char *buffer)\n{\n  int d, e, f;\n\n  ressuct = buffer; \/\/ ressu random buffer lookup\n  ressuct_bytes = size;\n\n  rndbits2 = 0;\n  clockbytes = 0;\n\n  cblocks = 0;\n  \n  for(d = 0; d &lt; RESSU_MIN_ROUNDS ||\n\t(copyreverse == 1 &amp;&amp; depth > 0 &amp;&amp; rndbits2 &lt; ressut_bits2_needed) ||\n\tclockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n    ressu_genbytes_single_do(size, buffer);\n  }\n\n  \/\/\n  \/\/  display statistics\n  \/\/\n  \n  if(stats) {\n\n    if(newressu_output == 1)\n      fprintf(stdout, \"\\n\");\n    newressu_output = 0;\n\n    fprintf(stderr, \"rounds:%d\", d);\n\n    long chains = 0;\n    \n    for(e = 0; e &lt; 1024; e++) {\n      if(periods&#91;e] > 0) {\n\tfprintf(stderr, \" %d:%lu\", e, periods&#91;e]);\n\tchains += periods&#91;e];\n      }\n    }\n\n    fprintf(stderr, \", chains:%ld\", chains);\n    fprintf(stderr, \", blocks:%ld\", cblocks);\n    \n#ifdef DEBUG_SORTED\n    \n    fprintf(stderr, \", sorted:\");\n\n    int g = 0;\n\n    for(;;) {\n      f = -1;\n      for(e = 0; e &lt; 1024; e++) {\n\tif( (f == -1 &amp;&amp; periods&#91;e] > g) ||\n\t    (periods&#91;e] > g &amp;&amp; f > periods&#91;e]) )\n\t  f = periods&#91;e];\n      }\n      if(f == -1)\n\tbreak;\n      \n      g = f;\n      fprintf(stderr,\" %d\", g);\n    }\n    \n#endif\n    \n    fprintf(stderr, \", clockbytes:%ld\", clockbytes);\n    fprintf(stderr, \", rndbits2:%d\", rndbits2);\n    fprintf(stderr, \"\\n\");\n    fflush(stderr);\n  }\n\n#ifdef DEBUG7\n\n  ressu_dump(\"fast\", size, buffer, 32);\n\n#endif\n  \n  genbytes += size;\n}\n\n#define aDEBUG3B 2\n\nvoid ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c, d, e, f;\n  static unsigned char ressut&#91;RESSUT_BYTES];\n  static int ressut_first = 1,\n    ressut_pos = 0;\n\n  unsigned long prevperiods&#91;1024];\n\n  ressuct = ressut;  \/\/ ressu random buffer lookup\n  ressuct_bytes = ressut_bytes; \/\/ table used in ressu_genbytes_single_do\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\n      rndbits1 = 0;\n      rndbits2 = 0;\n      rndbits3 = 0;\n      rndbits4 = 0;\n      rndbits5 = 0;\n      rndbits6 = 0;\n      rndbits7 = 0;\n      rndbits20 = 0;\n      rndbits21 = 0;\n      rndbits22 = 0;\n\n      cblocks = 0;\n      \n      int lim, lim1 = 0, lim2 = 0;\n      int lim1a, lim1b;\n      int high1, high2;\n\n      int rndbits3high;\n      int rndbits4highdigits;\n      int rndbits6high;\n      int rndbits6pos;\n      int rndbits7high;\n      \n      for(d = 0;\n\t  rndbits1 &lt; ressut_bits1_needed ||\n\t    (copyreverse == 1 &amp;&amp; depth > 0 &amp;&amp; rndbits2 &lt; ressut_bits2_needed) ||\n\t  rndbits3 &lt; ressut_bits3_needed ||\n\t  rndbits4 &lt; ressut_bits4_needed ||\n\t  rndbits5 &lt; ressut_bits5_needed ||\n\t  rndbits6 &lt; ressut_bits6_needed ||\n\t  rndbits7 &lt; ressut_bits7_needed ||\n\t  rndbits20 &lt; ressut_bits20_needed ||\n\t  rndbits21 &lt; ressut_bits21_needed ||\n\t  d &lt; RESSU_MIN_ROUNDS ||\n\t  clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n#define aDEBUG6 2\n\t\n\t\/\/\n\t\/\/  calculate rndbits1\n\t\/\/\n\t\n\t\/\/ save previous round\n\n        for(e = 0; e &lt; 1024; e++) {\n\t  prevperiods&#91;e] = periods&#91;e];\n\t}\n\n\tressu_genbytes_single_do(ressut_bytes, ressut);\n\n\t\/\/ find new lim1\n\t\n\tlim = lim1;\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(prevperiods&#91;e] > 0 &amp;&amp; prevperiods&#91;e] == lim) {\n\t    if(f == -1 || (periods&#91;e]>0 &amp;&amp; f&lt;periods&#91;e])) {\n\t      f  = periods&#91;e];\n\t    }\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim = f;\n\n\tlim1a = lim;\n\t\n\t\/\/ find highest amount of chains\n\t\n\thigh1 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(high1 == -1 || high1 &lt; periods&#91;e]) {\n\t    high1 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and second highest\n\t\n\thigh2 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (high2 == -1 &amp;&amp; periods&#91;e] &lt; high1) ||\n\t      (high2 &lt; periods&#91;e] &amp;&amp; periods&#91;e] &lt; high1) ) {\n\t    high2 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and average\n\n\tint psum = 0;\n\tint pcnt = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] > 0) {\n\t    psum += periods&#91;e];\n\t    pcnt++;\n\t  }\n\t}\n\n\tlim1b = (int)((double)psum \/ pcnt);\n\t\n\t\/\/ find next smaller than average\n\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (f == -1 &amp;&amp; periods&#91;e] &lt; lim1b) ||\n\t      (f &lt; periods&#91;e] &amp;&amp; periods&#91;e] &lt; lim1b) ) {\n\t    f = periods&#91;e];\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim1b = f;\n\n\tif(lim == 0 || lim > lim1b)\n\t  lim = lim1b;\n\n\t\/\/ if lim greater that second highest,\n\t\/\/ set to second highest\n\n\tif(lim > high2) {\n\t  lim = high2;\n\t}\n\t\t\n\tlim1 = lim;\n\n\t\/\/ find next greater than lim\n\t\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] > lim &amp;&amp;\n\t     (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\n\t\/\/ calculate rndbits1\n\n#define aDEBUG14A 2\n\t\n\trndbits1 = 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    rndbits1 += periods&#91;e];\n\t  }\n\t}\n\t\n\t\/\/\n\t\/\/  calculate rndbits3\n\t\/\/\n\n#define aDEBUG14C 2\n\t\n\trndbits3high = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits3high &lt; periods&#91;e])\n\t    rndbits3high = periods&#91;e];\n\t}\n\n\trndbits3 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits3high > periods&#91;e]) {\n\t    rndbits3 += periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits4\n\t\/\/\n\n#define aDEBUG14D 2\n\t\n\trndbits4highdigits = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &lt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4highdigits = (int)log10((double)periods&#91;e]) + 1;\n\t  }\n\t}\n\n\trndbits4 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits > (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4 += periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits5\n\t\/\/\n\n#define aDEBUG14E 2\n\t\n\trndbits5 = 0;\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  rndbits5 += periods&#91;e];\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits6\n\t\/\/\n\n#define aDEBUG14F 2\n\t\n\trndbits6high = 0;\n\trndbits6pos = 0;\n\trndbits6 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits6high &lt; periods&#91;e]) {\n\t    rndbits6high = periods&#91;e];\n\t    rndbits6pos = e;\n\t  }\n\t}\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits6high > periods&#91;e] &amp;&amp; periods&#91;e] > 0) {\n\t    if(rndbits6pos > e)\n\t      rndbits6 += log2((double)rndbits6pos - e) * periods&#91;e];\n\t    else\n\t      rndbits6 += log2((double)e - rndbits6pos) * periods&#91;e];\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits7\n\t\/\/\n\n#define aDEBUG14G 2\n\t\n\trndbits7high = 0;\n\trndbits7 = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits7high &lt; periods&#91;e])\n\t    rndbits7high = periods&#91;e];\n\t}\n\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(rndbits7high > periods&#91;e] &amp;&amp; periods&#91;e] > 0) {\n\t    rndbits7 += log2((double)rndbits7high - periods&#91;e]) * periods&#91;e];\n\t  }\n\t}\n      } \/\/ for(d = 0;\n      \n      \/\/\n      \/\/ debug display for rndbits1\n      \/\/\n\n#ifdef DEBUG14A\n\t\n      rndbits1 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(periods&#91;e] > 0 &amp;&amp; periods&#91;e] &lt; lim) {\n\t  rndbits1 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits1+prev:%d\", rndbits1);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits3\n      \/\/\n\n#ifdef DEBUG14C\n\t\n      rndbits3 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits3high > periods&#91;e] &amp;&amp;\n\t   periods&#91;e] > 0) {\n\t  rndbits3 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits3+prev:%d\", rndbits3);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits4\n      \/\/\n\n#ifdef DEBUG14D\n      \n      rndbits4 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits4highdigits > (int)log10((double)periods&#91;e]) + 1 &amp;&amp;\n\t   periods&#91;e] > 0) {\n\t  rndbits4 += periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", rndbits4+prev:%d\", rndbits4);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug display for rndbits5\n      \/\/\n\n#ifdef DEBUG14E\n\n      rndbits5 = 0;\n\n      for(e = 0; e &lt; 1024; e++) {\n\tif(periods&#91;e] > 0) {\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  rndbits5 += periods&#91;e];\n\t  fprintf(stderr,\", rndbits5+prev:%d\", rndbits5);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug diplay for rndbits6\n      \/\/\n\n#ifdef DEBUG14F\n\t\n      rndbits6 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits6high > periods&#91;e] &amp;&amp;\n\t   periods&#91;e] > 0) {\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%lu\", periods&#91;e]);\n\n\t  double l2;\n\n\t  if(rndbits6pos > e) {\n\t    fprintf(stderr,\", pos-e:%d\", rndbits6pos - e);\n\t    l2 = log2((double)rndbits6pos - e);\n\t  } else {\n\t    fprintf(stderr,\", e-pos:%d\", e - rndbits6pos);\n\t    l2 = log2((double)e - rndbits6pos);\n\t  }\n\t  fprintf(stderr,\", log2(prev):%f\", l2);\n\t  fprintf(stderr,\", periods*prev:%ld\", (long int) ((double)periods&#91;e] * l2));\n\t  rndbits6 += l2 * periods&#91;e];\n\t  fprintf(stderr,\", rndbits6+prev:%d\", rndbits6);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      \/\/\n      \/\/  debug diplay for rndbits7\n      \/\/\n\n#ifdef DEBUG14G\n\t\n      rndbits7 = 0;\n      for(e = 0; e &lt; 1024; e++) {\n\tif(rndbits7high > periods&#91;e] &amp;&amp;\n\t   periods&#91;e] > 0) {\n\t  rndbits7 += log2((double)rndbits7high - periods&#91;e]) * periods&#91;e];\n\t  fprintf(stderr,\"e:%d\", e);\n\t  fprintf(stderr,\", periods:%ld\", periods&#91;e]);\n\t  fprintf(stderr,\", high-prev:%ld\", rndbits7high-periods&#91;e]);\n\t  double l2=log2((double)rndbits7high-periods&#91;e]);\n\t  fprintf(stderr,\", log2(prev):%f\", l2);\n\t  fprintf(stderr,\", periods*prev:%ld\", (long int) ((double)periods&#91;e] * l2));\n\t  fprintf(stderr,\", rndbits7+prev:%d\", rndbits7);\n\t  fprintf(stderr,\"\\n\");\n\t}\n      }\n\n#endif\n      \n      if(stats) {\n\n\tif(newressu_output == 1)\n\t  fprintf(stderr,\"\\n\");\n\tnewressu_output = 0;\n\t\n\t\/\/\n\t\/\/  display statistics\n\t\/\/\n\tfprintf(stderr, \"rounds:%d\", d);\n\tlong chains = 0;\n    \n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] > 0) {\n\t    fprintf(stderr, \" %d:%lu\", e, periods&#91;e]);\n\t    chains += periods&#91;e];\n\t  }\n\t}\n\n\tfprintf(stderr, \", chains:%ld\", chains);\n\tfprintf(stderr, \", blocks:%ld\", cblocks);\n\t\n#ifdef DEBUG_SORTED\n\t\n\tfprintf(stderr, \", sorted:\");\n\tint g = 0;\n\tfor(;;) {\n\t  f = -1;\n\t  for(e = 0; e &lt; 1024; e++) {\n\t    if( (f == -1 &amp;&amp; periods&#91;e] > g) ||\n\t\t(periods&#91;e] > g &amp;&amp; f > periods&#91;e]) )\n\t      f = periods&#91;e];\n\t  }\n\t  if(f == -1)\n\t    break;\n\n\t  g = f;\n\t  fprintf(stderr,\" %d\", g);\n\t}\n\t\n#endif\n\tfprintf(stderr, \", ressut size:%d\", ressut_bytes);\n\tfprintf(stderr, \", high1:%d\", high1);\n\tfprintf(stderr, \", high2:%d\", high2);\n\tfprintf(stderr, \", lim1a:%d\", lim1a);\n\tfprintf(stderr, \", lim1b:%d\", lim1b);\n\tfprintf(stderr, \", lim1:%d\", lim1);\n\tfprintf(stderr, \", lim2:%d\", lim2);\n\tfprintf(stderr, \", div:%f\", (double)lim2 \/ lim1);\n\tfprintf(stderr, \", clockbytes:%ld\", clockbytes);\n\tfprintf(stderr, \", rndbits1:%d\", rndbits1);\n\tfprintf(stderr, \", rndbits2:%d\", rndbits2);\n\tfprintf(stderr, \", rndbits3high:%d\", rndbits3high);\n\tfprintf(stderr, \", rndbits3:%d\", rndbits3);\n\tfprintf(stderr, \", rndbits4highdigits:%d\", rndbits4highdigits);\n\tfprintf(stderr, \", rndbits4:%d\", rndbits4);\n\tfprintf(stderr, \", rndbits5:%d\", rndbits5);\n\tfprintf(stderr, \", rndbits6high:%d\", rndbits6high);\n\tfprintf(stderr, \", rndbits6:%d\", rndbits6);\n\tfprintf(stderr, \", rndbits7high:%d\", rndbits7high);\n\tfprintf(stderr, \", rndbits7:%d\", rndbits7);\n\tfprintf(stderr, \", rndbits20:%d\", rndbits20);\n\tfprintf(stderr, \", rndbits21:%d\", rndbits21);\n\tfprintf(stderr, \", rndbits22:%d\", rndbits22);\n\tfprintf(stderr, \", 20-21:%d\", rndbits20 - rndbits21);\n\tfprintf(stderr, \", 21-22:%d\", rndbits21 - rndbits22);\n\tfprintf(stderr, \"\\n\");\n\tfflush(stderr);\n      } \/\/ if(stats\n    } \/\/ if(ressut_pos == 0)\n    buffer&#91;c] ^= ressut&#91;ressut_pos];\n    ressut_pos = (ressut_pos + 1) % ressut_bytes;\n#ifdef OLD1\n    ressut_f = (ressut_f + ressut&#91;ressut_pos] + 2) % ressut_bytes; \/\/ bad for randomness... JariK 2023\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos + 1) % ressut_bytes;\n#endif\n  } \/\/ for(c = 0; c &lt; size; c++)\n\n  if(verbose) {\n    fprintf(stdout,\"ressu \");\n    for(c = 0; c &lt; size; c++) {\n      if(c > 0 &amp;&amp; c % 32 == 0)\n\tfprintf(stdout,\" \");\n      fprintf(stdout,\"%02x\", buffer&#91;c]);\n      newressu_output = 1;\n    }\n    fprintf(stdout,\"\\n\");\n  }\n  \n#ifdef DEBUG7\n\n  ressu_dump(\"genbytes\", size, buffer, 32);\n\n#endif\n  \n  genbytes += size;\n}\n\n#define aDEBUG20 2\n\nunsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n\n#ifdef DEBUG20\n  ressu_dump(\"cvar\", cvarsize + 1, cvar, 32);\n#endif\n}\n\n#define aCVARRANDOMSTART 2 \/\/ off by default\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n  \n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n#ifdef CVARRANDOMSTART\n  ressu_genbytes(8, (unsigned char *)&amp;cvar);  \n#endif\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}\n\n#ifdef SHA256\n\n#define PSEUDORESSU_LIMIT 1048576 \/\/ limit between rekeys\n#define TOPUP_BYTES 32*1024 \/\/ bytes between topups\n#define TOPUP_SIZE 32 \/\/ topup size in bytes (32 bytes, 256 bits)\n#define aTOPUP_TWICE 2 \/\/ off by default\n\nunsigned long topup_bytes = TOPUP_BYTES;\n\nstatic unsigned char pseudoressu_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void pseudoressu_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic void pseudoressu_addrandomness(int size, unsigned char *buffer)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu_key, sizeof(pseudoressu_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashUpdate(&amp;hash, buffer, size);\n  HashFinal(pseudoressu_key, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\n#define aDEBUG23 2\n\nstatic void pseudoressu_topup()\n{\n  unsigned char topup&#91;TOPUP_SIZE]; \/\/ 32 bytes, 256 bits\n\n  ressu_genbytes(sizeof(topup), topup);\n#ifdef DEBUG23\n  ressu_dump(\"topup\", sizeof(topup), topup, 32);\n#endif\n  pseudoressu_addrandomness(sizeof(topup), topup);\n\n  memset(&amp;topup, 0, sizeof(topup)); \/\/ forget topup\n}\n\nvoid pseudoressu_bytes(int size, unsigned char *buffer) \/\/ JariK 2022\n{\n  unsigned int n, blockbytes = 0;\n  unsigned char digest&#91;HashLen]; \/\/ 32 bytes, 256 bits\n  static unsigned int initneeded = 1, topup_counter = 0;\n\n  if(verbose)\n    fprintf(stdout,\"pseudoressu\");\n\n  while(size > 0) {\n\n    if(topup_counter == 0) {\n      if(initneeded) {\n\tressu_genbytes(sizeof(pseudoressu_key), pseudoressu_key); \/\/ set first key\n#ifdef DEBUG23\n\tressu_dump(\"first key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n\tinitneeded = 0;\n      }\n\n      pseudoressu_topup(); \/\/ add randomness to key\n#ifdef TOPUP_TWICE\n      pseudoressu_topup(); \/\/ add randomness to key\n#endif\n\n      topup_counter = topup_bytes;\n      blockbytes = 0;\n    } \/\/ end of if(topup_counter &lt;= 0\n\n    pseudoressu_internalbytes(digest); \/\/ get random bits using the key\n\n    \/\/ n = smallest from size, digest and topup_counter\n    \n    n = (size &lt; sizeof(digest) ? size : sizeof(digest));\n    n = (topup_counter &lt; n ? topup_counter : n);\n    \/\/fprintf(stderr,\", n:%d\",n);\n\n    for(int c = 0; c &lt; n; c++)\n      buffer&#91;c] ^= digest&#91;c];\n\n#ifdef DEBUG23\n    ressu_dump(\"newdata\", n, buffer, 32);\n#endif\n\n    if(verbose) {\n      fprintf(stdout,\" \");\n      for(int c = 0; c &lt; n; c++)\n\tfprintf(stdout,\"%02x\", digest&#91;c]);\n      newressu_output = 1;\n    }\n\n    buffer += n;\n    size -= n;\n    topup_counter -= n;\n    \n    blockbytes += n;\n\n    if(blockbytes >= PSEUDORESSU_LIMIT &amp;&amp; size > 0) {\n\n      pseudoressu_internalbytes(pseudoressu_key); \/\/ replace key with new random one\n#ifdef DEBUG23\n      ressu_dump(\"rekey\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n      blockbytes = 0;\n    }\n\n  } \/\/ end of while(size > 0\n  \n  pseudoressu_internalbytes(pseudoressu_key); \/\/ replace key with new random one\n#ifdef DEBUG23\n  ressu_dump(\"new key\", sizeof(pseudoressu_key), pseudoressu_key, 32);\n#endif\n  \/\/ memset(&amp;digest, 0, sizeof(digest)); \/\/ forget digest\n}\n\nvoid ressutwist_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  ressu_genbytes(size, buffer);\n  pseudoressu_bytes(size, buffer);\n}\n\n#endif \/\/ end of #ifdef SHA256\n\n#ifdef SHA256\n\nvoid dumpbin(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    if(isprint(buf&#91;c]) &amp;&amp; buf&#91;c]!= ' ')\n      fputc(buf&#91;c], stderr);\n    else\n      fprintf(stderr,\"\\\\%02x\", buf&#91;c]);\n}\n\nvoid dumpline(FILE *fp1, int len, unsigned char *buf)\n{\n  int c;\n\n  for(c = 0; c &lt; len; c++)\n    fprintf(fp1,\"%02x\", buf&#91;c]);\n}\n\n#define DEBUG17 2\n\nstatic unsigned char stream_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void stream_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic int streamt_pos = 0;\nstatic unsigned long streamt_input_bytes = 0;\n\n#define STREAM_REKEY 2048 \/\/ rekey blocksize now 2048\n\nvoid stream_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  int c;\n  static unsigned char streamt&#91;HashLen]; \/\/ 32 bytes, 256 bits\n  \n  for(c = 0; c &lt; size; c++) {\n\n    if(streamt_pos == 0) {\n\n      if(streamt_input_bytes % STREAM_REKEY == 0) {\n\tstream_internalbytes(stream_key); \/\/ change key, first block also\n#ifdef DEBUG17\n\tressu_dump(\"rekey\", sizeof(stream_key), stream_key, 32);\n#endif\n      }\n\n      stream_internalbytes(streamt); \/\/ read next random bytes\n#ifdef DEBUG17\n      ressu_dump(\"nextdata\", sizeof(streamt), streamt, 32);\n#endif\n      \n      streamt_input_bytes += sizeof(streamt);\n    } \/\/ end of if(streamt_pos == 0\n\n    buffer&#91;c] = streamt&#91;streamt_pos];\n    streamt_pos = (streamt_pos + 1) % sizeof(streamt);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n}\n\n#define STREAM_KEY_ROUNDS 4096 \/\/ should be fast enough and slow enough, now 4096\n\nvoid stream_open(int size, unsigned char *key) \/\/ size = 0 --> zero terminated string\n{\n  int c;\n  HashCtx hash;\n\n  clearcvar();\n  streamt_pos = 0;  \n  streamt_input_bytes = 0;  \n\n  if(size == 0)\n    size = strlen(key);\n  \n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, key, size);\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n\n  for(c = 0; c &lt; STREAM_KEY_ROUNDS; c++) {\n\n    HashFinal(stream_key, &amp;hash);\n\n    HashInit(&amp;hash);\n    HashUpdate(&amp;hash, stream_key, sizeof(stream_key));\n    HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n    inccvar();\n  }\n\n  HashFinal(stream_key, &amp;hash);\n\n#define DEBUG21 2\n\n#ifdef DEBUG21\n  fflush(stdout);\n  fprintf(stderr,\"%s: stream_open():\", procname);\n  fprintf(stderr,\" randomness from key, key=\");\n  dumpbin(stderr, size, key);\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n#endif\n\n\n#ifdef DEBUG17\n  ressu_dump(\"first key\", sizeof(stream_key), stream_key, 32);\n#endif\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\n#endif \/\/ end of #ifdef SHA256\n\nvoid readfile_xor(int size,\n    unsigned char *buffer,\n    unsigned char *filename)\n{\n  int c, n;\n  unsigned char temp&#91;64];\n  FILE *fp1;\n\n  if((fp1 = fopen(filename, \"rb\")) == NULL) {\n    fprintf(stderr,\"%s: fopen(): cannot open file %s\\n\",\n\t    procname, filename);\n    exit(1);\n  }\n  while(size > 0) {\n    n = (size &lt; sizeof(temp)) ? size : sizeof(temp);\n    if(fread(temp, 1, n, fp1) &lt; n) {\n      fprintf(stderr,\"%s: fread(): cannot read file %s\\n\",\n\t      procname, filename);\n      exit(1);\n    }\n    for(c = 0; c &lt; n; c++)\n      buffer&#91;c] ^= temp&#91;c];\n    size -= n;\n    buffer += n;\n  }\n  fclose(fp1);\n  \n  memset(temp, 0, sizeof(temp)); \/\/ forget temp\n}\n\nstatic unsigned char urandomfilename&#91;128] = \"\/dev\/urandom\";\n\nvoid urandom_bytes(int size, unsigned char *buffer)\n{\n  readfile_xor(size, buffer, urandomfilename);\n}\n\n#ifdef USE_RANDOM\n\nstatic unsigned char randomfilename&#91;128] = \"\/dev\/random\";\n\nvoid random_bytes(int size, unsigned char *buffer)\n{\n  readfile_xor(size, buffer, randomfilename);\n}\n\n#endif\n\nvoid test_bytes(int size, unsigned char *buffer) \/\/ JariK 2023\n{\n  \/\/ insert your generator here, run it with\n  \/\/ --test command line parameter (source for\n  \/\/ randomness)\n\n  ressutwist_bytes(size, buffer);\n  urandom_bytes(size, buffer);\n  \n  \/\/memset(buffer, 0, size);\n\n  \/\/for(int c = 0; c &lt; size; c++)\n  \/\/  buffer&#91;c] = c &amp; 0xff;\n}\n\nvoid newressu_version()\n{\n  fprintf(stderr, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stderr, \", %s\", copyright);\n}\n\n#ifdef MAIN\n\n#include &lt;unistd.h>\n#include &lt;ctype.h>\n#include &lt;malloc.h>\n\n#include \"newressu.h\"\n\n#define SAMPLE_WRITE 2 \/\/ on by default\n#define SAMPLE_HASH 2 \/\/ on by default (for now)\n#define SAMPLE_SYNC 2 \/\/ on by default (for now (exfat))\n#define USE_TIMER 2\n#define aUSE_DUMMY 2\n\nvoid command_readline(unsigned char *command, int linelen, unsigned char *line)\n{\n  FILE *fp1;\n\n  line&#91;0] = '\\0';\n  \n  if((fp1 = popen(command, \"r\")) == NULL) {\n    fprintf(stdout,\"%s: popen(): cannot open process '%s'\\n\",\n\t    procname, command);\n  } else  {\n    fgets(line, linelen, fp1);\n    if(line&#91;strlen(line)-1] == '\\n')\n      line&#91;strlen(line)-1] = '\\0';\n  }\n}\n\nlong long command_countlines(unsigned char *command)\n{\n  unsigned char buffer&#91;1024];\n  long long ll = 0;\n  FILE *fp1;\n\n  if((fp1 = popen(command, \"r\")) == NULL) {\n    fprintf(stdout,\"%s: popen(): cannot open process '%s'\\n\",\n\t    procname, command);\n  } else  {\n    while(fgets(buffer, sizeof(buffer), fp1) != NULL)\n      ll++;\n  }\n  return(ll);\n}\n\n#define aDEBUG25 \/\/ off by default\n#define aDEBUG19 \/\/ off by default\n\n#ifdef DEBUG19\n\nvoid save_path(int path_length, unsigned char *path)\n{\n  if((getcwd(path, path_length)) == NULL) {\n    fprintf(stdout,\"%s: save_path(): cannot get working directory (getcwd())\\n\",\n\t    procname);\n  }\n#ifdef DEBUG25\n  fprintf(stderr,\"%s: save_path(): saved current path (getcwd()), path = %s\\n\",\n\t  procname, path);\n#endif\n}\n\nint exists_path(unsigned char *path)\n{\n  FILE *fp1;\n  \n  if((fp1 = fopen(path, \"r\")) != NULL) {\n    fclose(fp1);\n    \/\/fprintf(stderr,\"path %s ok\\n\", path);\n    return(1);\n  } else\n    return(0);\n}\n\nvoid set_path(unsigned char *path)\n{\n  if(chdir(path) != 0) {\n    fprintf(stdout,\"%s: set_path(): cannot change directory (chdir())\\n\",\n\t    procname);\n  }\n#ifdef DEBUG25\n  fprintf(stderr,\"%s: set_path(): set path (chdir()), path = %s\\n\",\n\t  procname, path);\n#endif\n}\n\n#endif \/\/ end of #ifdef DEBUG19\n\nunsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)\n{\n  int nlen = strlen(needle);;\n  unsigned char *p = haystack;\n\n  while(*p != '\\0') {\n    if(!strncmp(p, needle, nlen) &amp;&amp;\n       ( isblank(*(p + nlen)) || ispunct(*(p + nlen)) || *(p + nlen) == '\\0' ) &amp;&amp; \/\/ character after string\n       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) \/\/ character before string\n      return(p);\n    p++;\n  }\n  return(NULL);\n}\n\n#ifdef OLD1\n\nunsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)\n{\n  int fl;\n  unsigned char *p = haystack;\n\n  while(*p != '\\0') {\n    fl = strlen(needle);\n    if(!strncmp(p, needle, strlen(needle)) &amp;&amp;\n       ( isblank(*(p + fl)) || ispunct(*(p + fl)) || *(p + fl) == '\\0' ) &amp;&amp; \/\/ character after string\n       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) { \/\/ character before string\n      return(p);\n    }\n    p++;\n  }\n  return(NULL);\n}\n\n#endif\n\n\/*\n *  code for flags functions\n *\/\n\/*\n\ud83c\udde6\n\ud83c\udde7\n\ud83c\udde8\n\ud83c\udde9\n\ud83c\uddea\n\ud83c\uddeb\n\ud83c\uddec\n\ud83c\udded\n\ud83c\uddee\n\ud83c\uddef\n\ud83c\uddf0\n\ud83c\uddf1\n\ud83c\uddf2\n\ud83c\uddf3\n\ud83c\uddf4\n\ud83c\uddf5\n\ud83c\uddf6\n\ud83c\uddf7\n\ud83c\uddf8\n\ud83c\uddf9\n\ud83c\uddfa\n\ud83c\uddfb\n\ud83c\uddfc\n\ud83c\uddfd\n\ud83c\uddfe\n\ud83c\uddff\n*\/\n\/*\n  \ud83c\udde6\ud83c\udde7\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddeb\ud83c\uddec\ud83c\udded\ud83c\uddee\ud83c\uddef\ud83c\uddf0\ud83c\uddf1\ud83c\uddf2\ud83c\uddf3\ud83c\uddf4\ud83c\uddf5\ud83c\uddf6\ud83c\uddf7\ud83c\uddf8\ud83c\uddf9\ud83c\uddfa\ud83c\uddfb\ud83c\uddfc\ud83c\uddfd\ud83c\uddfe\ud83c\uddff\n*\/\n\nstruct idflags { \/\/ 202307 JariK\n  unsigned char *id;\n  unsigned char *flags;\n} idsflags&#91;] = {\n  { \"\ud83c\uddeb\ud83c\uddee\", \"\ud83c\uddeb\ud83c\uddee: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND\" },\n  { \"\ud83c\udde6\ud83c\uddfd\", \"\ud83c\udde6\ud83c\uddfd: ax, ala, \u00c5land, aland, NORDIC, FINLAND\" },\n  { \"\ud83c\uddf8\ud83c\uddea\", \"\ud83c\uddf8\ud83c\uddea: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\uddf3\ud83c\uddf4\", \"\ud83c\uddf3\ud83c\uddf4: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\udde9\ud83c\uddf0\", \"\ud83c\udde9\ud83c\uddf0: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK\" },\n  { \"\ud83c\uddeb\ud83c\uddf4\", \"\ud83c\uddeb\ud83c\uddf4: fo, fro, FaroeIslands, NORDIC, DENMARK\" },\n  { \"\ud83c\uddee\ud83c\uddf8\", \"\ud83c\uddee\ud83c\uddf8: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC\" },\n  { \"\ud83c\uddec\ud83c\uddf1\", \"\ud83c\uddec\ud83c\uddf1: gl, grl, Greenland, NORTHAMERICA, NORDIC, DENMARK\" },\n  \n  { \"\ud83c\uddea\ud83c\uddea\", \"\ud83c\uddea\ud83c\uddea: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddfb\", \"\ud83c\uddf1\ud83c\uddfb: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  { \"\ud83c\uddf1\ud83c\uddf9\", \"\ud83c\uddf1\ud83c\uddf9: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC\" },\n  \n  { \"\ud83c\uddfa\ud83c\udde6\", \"\ud83c\uddfa\ud83c\udde6: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf1\", \"\ud83c\udde6\ud83c\uddf1: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\udde9\", \"\ud83c\udde6\ud83c\udde9: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf2\", \"\ud83c\udde6\ud83c\uddf2: am, arm, Armenia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde6\ud83c\uddf9\", \"\ud83c\udde6\ud83c\uddf9: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde6\ud83c\uddff\", \"\ud83c\udde6\ud83c\uddff: az, aze, Azerbaijan, EASTERNEUROPE, EUROPE, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddfe\", \"\ud83c\udde7\ud83c\uddfe: by, blr, Belarus, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddea\", \"\ud83c\udde7\ud83c\uddea: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udde6\", \"\ud83c\udde7\ud83c\udde6: ba, bih, BosniaandHerzegovina, EASTERNEUROPE, EUROPE\" }, \/\/ Bosnia and Herzegovina\n  { \"\ud83c\udde7\ud83c\uddec\", \"\ud83c\udde7\ud83c\uddec: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udded\ud83c\uddf7\", \"\ud83c\udded\ud83c\uddf7: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\uddfe\", \"\ud83c\udde8\ud83c\uddfe: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde8\ud83c\uddff\", \"\ud83c\udde8\ud83c\uddff: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA\" },  \/\/ Czech Republic Czechia\n  { \"\ud83c\uddeb\ud83c\uddf7\", \"\ud83c\uddeb\ud83c\uddf7: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddec\ud83c\uddea\", \"\ud83c\uddec\ud83c\uddea: ge, geo, Georgia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  { \"\ud83c\udde9\ud83c\uddea\", \"\ud83c\udde9\ud83c\uddea: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddec\ud83c\uddf7\", \"\ud83c\uddec\ud83c\uddf7: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udded\ud83c\uddfa\", \"\ud83c\udded\ud83c\uddfa: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf9\", \"\ud83c\uddee\ud83c\uddf9: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddfb\ud83c\udde6\", \"\ud83c\uddfb\ud83c\udde6: va, vat, Vatican, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddff\", \"\ud83c\uddf0\ud83c\uddff: kz, kaz, Kazakhstan, EUROPE, EURASIA, CENTRALASIA, ASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddee\", \"\ud83c\uddf1\ud83c\uddee: li, lie, Liechtenstein, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddfa\", \"\ud83c\uddf1\ud83c\uddfa: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf9\", \"\ud83c\uddf2\ud83c\uddf9: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\udde9\", \"\ud83c\uddf2\ud83c\udde9: md, mda, Moldova, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddea\", \"\ud83c\uddf2\ud83c\uddea: me, mne, Montenegro, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\udde8\", \"\ud83c\uddf2\ud83c\udde8: mc, mco, Monaco, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddea\", \"\ud83c\uddf2\ud83c\uddea: me, mne, Montenegro, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf1\", \"\ud83c\uddf3\ud83c\uddf1: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf0\", \"\ud83c\uddf2\ud83c\uddf0: mk, mkd, Northmacedonia, EASTERNEUROPE, EUROPE, EURASIA\" }, \/\/ North Macedonia\n  { \"\ud83c\uddf5\ud83c\uddf1\", \"\ud83c\uddf5\ud83c\uddf1: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf9\", \"\ud83c\uddf5\ud83c\uddf9: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf7\ud83c\uddf4\", \"\ud83c\uddf7\ud83c\uddf4: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf7\ud83c\uddfa\", \"\ud83c\uddf7\ud83c\uddfa: ru, rus, Russia, EASTERNEUROPE, EUROPE, EURASIA, NORTHASIA, ASIA, BRICS\" },\n  { \"\ud83c\uddf8\ud83c\uddf2\", \"\ud83c\uddf8\ud83c\uddf2: sm, smr, SanMarino, SOUTHERNEUROPE, EUROPE, EURASIA\" }, \/\/ San Marino\n  { \"\ud83c\uddf7\ud83c\uddf8\", \"\ud83c\uddf7\ud83c\uddf8: rs, srb, Serbia, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddf0\", \"\ud83c\uddf8\ud83c\uddf0: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddee\", \"\ud83c\uddf8\ud83c\uddee: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddea\ud83c\uddf8\", \"\ud83c\uddea\ud83c\uddf8: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\udded\", \"\ud83c\udde8\ud83c\udded: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf7\", \"\ud83c\uddf9\ud83c\uddf7: tr, tur, Turkey, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA\" },\n  \n  { \"\ud83c\uddec\ud83c\udde7\", \"\ud83c\uddec\ud83c\udde7: gb, gbr, UnitedKingdom, UK, WESTERNEUROPE, EUROPE, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, England, UK\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, Scotland, UK\" },\n  { \"\ud83c\uddee\ud83c\uddea\", \"\ud83c\uddee\ud83c\uddea: gb, gbr, Wales, UK\" },\n\n  { \"\ud83c\uddec\ud83c\uddee\", \"\ud83c\uddec\ud83c\uddee: gi, gib, Gibraltar, UK\" },\n\n  { \"\ud83c\uddf8\ud83c\uddef\", \"\ud83c\uddf8\ud83c\uddef: sj, sjm, JanMayen, NORWAY\" }, \/\/ Jan Mayen\n  \n  { \"\ud83c\udde6\ud83c\uddee\", \"\ud83c\udde6\ud83c\uddee: ai, aia, Anguilla, NORTHAMERICA, UK\" },\n  { \"\ud83c\udde6\ud83c\uddec\", \"\ud83c\udde6\ud83c\uddec: ag, atg, AntiguaAndBarbuda, NORTHAMERICA\" }, \/\/ Antigua and Barbuda \n  { \"\ud83c\udde6\ud83c\uddfc\", \"\ud83c\udde6\ud83c\uddfc: aw, sbw, Aruba, NORTHAMERICA\" }, \n  { \"\ud83c\udde7\ud83c\uddf8\", \"\ud83c\udde7\ud83c\uddf8: bs, bhs, Bahamas, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\udde7\", \"\ud83c\udde7\ud83c\udde7: bb, brb, Barbados, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddff\", \"\ud83c\udde7\ud83c\uddff: bz, blz, Belize, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf2\", \"\ud83c\udde7\ud83c\uddf2: bm, bmu, Bermuda, UK, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf6\", \"\ud83c\udde7\ud83c\uddf6: bq, bes, Bonaire, NETHERLANDS, NORTHAMERICA\" },\n  { \"\ud83c\uddfb\ud83c\uddec\", \"\ud83c\uddfb\ud83c\uddec: vg, vgb, BritishVirginIslands, UK, NORTHAMERICA\" }, \/\/ British Virgin Islands\n  { \"\ud83c\udde8\ud83c\udde6\", \"\ud83c\udde8\ud83c\udde6: ca, can, Canada, NORTHAMERICA\" },\n  { \"\ud83c\uddf0\ud83c\uddfe\", \"\ud83c\uddf0\ud83c\uddfe: ky, cym, CaymanIslands, UK, NORTHAMERICA\" },\n  { \"\ud83c\uddeb\ud83c\uddf7\", \"\ud83c\uddeb\ud83c\uddf7: fr, fra, ClippertonIsland, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddf7\", \"\ud83c\udde8\ud83c\uddf7: cr, cri, CostaRica, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddfa\", \"\ud83c\udde8\ud83c\uddfa: cu, cub, Cuba, NORTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddfc\", \"\ud83c\udde8\ud83c\uddfc: cw, cuw, Cura\u00e7ao, curacao, NORTHAMERICA\" },\n  { \"\ud83c\udde9\ud83c\uddf2\", \"\ud83c\udde9\ud83c\uddf2: dm, dma, Dominica, NORTHAMERICA\" },\n  { \"\ud83c\udde9\ud83c\uddf4\", \"\ud83c\udde9\ud83c\uddf4: do, dom, DominicanRepublic, NORTHAMERICA\" }, \/\/ Dominican Republic\n  { \"\ud83c\uddf8\ud83c\uddfb\", \"\ud83c\uddf8\ud83c\uddfb: sv, slv, ElSalvador, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf1\", \"\ud83c\uddec\ud83c\uddf1: gl, grl, Greenland, DENMARK, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\udde9\", \"\ud83c\uddec\ud83c\udde9: gd, grd, Grenada, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf5\", \"\ud83c\uddec\ud83c\uddf5: gp, glp, Guadeloupe, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf9\", \"\ud83c\uddec\ud83c\uddf9: gt, gtm, Guatemala, NORTHAMERICA\" },\n  { \"\ud83c\udded\ud83c\uddf9\", \"\ud83c\udded\ud83c\uddf9: ht, hti, Haiti, NORTHAMERICA\" },\n  { \"\ud83c\udded\ud83c\uddf3\", \"\ud83c\udded\ud83c\uddf3: hn, hnd, Honduras, NORTHAMERICA\" },\n  { \"\ud83c\uddef\ud83c\uddf2\", \"\ud83c\uddef\ud83c\uddf2: jm, jam, Jamaica, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf6\", \"\ud83c\uddf2\ud83c\uddf6: mq, mtq, Martinique, FRANCE, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfd\", \"\ud83c\uddf2\ud83c\uddfd: mx, mex, Mexico, NORTHAMERICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf8\", \"\ud83c\uddf2\ud83c\uddf8: ms, msr, Montserrat, UK, NORTHAMERICA\" },\n  { \"\ud83c\uddf3\ud83c\uddee\", \"\ud83c\uddf3\ud83c\uddee: ni, nic, Nicaragua, NORTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\udde6\", \"\ud83c\uddf5\ud83c\udde6: pa, pan, Panama, NORTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddf7\", \"\ud83c\uddf5\ud83c\uddf7: pr, pri, PuertoRico, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf6\", \"\ud83c\udde7\ud83c\uddf6: bq, bes, Saba, NORTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf1\", \"\ud83c\udde7\ud83c\uddf1: bl, blm, SaintBarth\u00e9lemy, saintbarthelemy, NORTHAMERICA\" }, \/\/ Saint Barth\u00e9lemy\n  { \"\ud83c\uddf0\ud83c\uddf3\", \"\ud83c\uddf0\ud83c\uddf3: kn, kna, SaintKitts, NORTHAMERICA\" }, \/\/ Saint Kitts and Nevis\n  { \"\ud83c\uddf1\ud83c\udde8\", \"\ud83c\uddf1\ud83c\udde8: lc, lca, SaintLucia, NORTHAMERICA\" }, \/\/ Saint Lucia\n  { \"\ud83c\uddf2\ud83c\uddeb\", \"\ud83c\uddf2\ud83c\uddeb: mf, maf, SaintMartin, NORTHAMERICA\" }, \/\/ Collectivity of Saint Martin\n  { \"\ud83c\uddf8\ud83c\uddfd\", \"\ud83c\uddf8\ud83c\uddfd: sx, sxm, SintMaarten, NORTHAMERICA\" }, \/\/ Sint Maarten\n  { \"\ud83c\uddf9\ud83c\uddf9\", \"\ud83c\uddf9\ud83c\uddf9: tt, tto, TrinidadandTobago, NORTHAMERICA\" }, \/\/ Trinidad and Tobago\n  { \"\ud83c\uddf9\ud83c\udde8\", \"\ud83c\uddf9\ud83c\udde8: tc, tca, TurksandCaicos, UK, NORTHAMERICA\" }, \/\/ Turks and Caicos Islands\n  { \"\ud83c\uddf5\ud83c\uddf2\", \"\ud83c\uddf5\ud83c\uddf2: pm, spm, SaintPierre, NORTHAMERICA\" }, \/\/ Saint Pierre and Miquelon\n  { \"\ud83c\uddfb\ud83c\udde8\", \"\ud83c\uddfb\ud83c\udde8: vc, vct, SaintVincent, NORTHAMERICA\" }, \/\/ Saint Vincent and the Grenadines\n  { \"\ud83c\uddfa\ud83c\uddf8\", \"\ud83c\uddfa\ud83c\uddf8: us, usa, UnitedStatesofAmerica, USA, NORTHAMERICA\" }, \/\/ United States of America\n  { \"\ud83c\uddfb\ud83c\uddee\", \"\ud83c\uddfb\ud83c\uddee: vi, vir, VirginIslands, USA, NORTHAMERICA\" }, \/\/ United States Virgin Islands\n\n  { \"\ud83c\udde7\ud83c\uddfb\", \"\ud83c\udde7\ud83c\uddfb: bv, bvt, BouvetIsland\" }, \/\/ Bouvet Island\n  { \"\ud83c\uddfa\ud83c\uddf2\", \"\ud83c\uddfa\ud83c\uddf2: um, umi, Navassa\" },\n  { \"\ud83c\uddf8\ud83c\udded\", \"\ud83c\uddf8\ud83c\udded: sh, shn, SaintHelena\" }, \/\/ Saint Helena\n  \n  { \"\ud83c\udde6\ud83c\uddf7\", \"\ud83c\udde6\ud83c\uddf7: ar, arg, Argentina, SOUTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf4\", \"\ud83c\udde7\ud83c\uddf4: bo, bol, Bolivia, SOUTHAMERICA\" },\n  { \"\ud83c\udde7\ud83c\uddf7\", \"\ud83c\udde7\ud83c\uddf7: br, bra, Brazil, SOUTHAMERICA, BRICS\" },\n  { \"\ud83c\udde8\ud83c\uddf1\", \"\ud83c\udde8\ud83c\uddf1: cl, chl, Chile, SOUTHAMERICA\" },\n  { \"\ud83c\udde8\ud83c\uddf4\", \"\ud83c\udde8\ud83c\uddf4: co, col, Colombia, SOUTHAMERICA\" },\n  { \"\ud83c\uddea\ud83c\udde8\", \"\ud83c\uddea\ud83c\udde8: ec, ecu, Ecuador, SOUTHAMERICA\" },\n  { \"\ud83c\uddeb\ud83c\uddf0\", \"\ud83c\uddeb\ud83c\uddf0: fk, flk, FalklandIslands, UK, SOUTHAMERICA\" }, \/\/ Falkland Islands\n  { \"\ud83c\uddec\ud83c\uddeb\", \"\ud83c\uddec\ud83c\uddeb: gf, guf, FrenchGuiana, SOUTHAMERICA, FRANCE\" }, \/\/ French Guiana\n  { \"\ud83c\uddec\ud83c\uddfe\", \"\ud83c\uddec\ud83c\uddfe: gy, guy, Guyana, SOUTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddfe\", \"\ud83c\uddf5\ud83c\uddfe: py, pry, Paraguay, SOUTHAMERICA\" },\n  { \"\ud83c\uddf5\ud83c\uddea\", \"\ud83c\uddf5\ud83c\uddea: pe, per, Peru, SOUTHAMERICA\" },\n  { \"\ud83c\uddec\ud83c\uddf8\", \"\ud83c\uddec\ud83c\uddf8: gs, sgs, SouthGeorgia, SOUTHAMERICA\" }, \/\/ South Georgia and the South Sandwich Islands\n  { \"\ud83c\uddf8\ud83c\uddf7\", \"\ud83c\uddf8\ud83c\uddf7: sr, sur, Suriname, SOUTHAMERICA\" },\n  { \"\ud83c\uddfa\ud83c\uddfe\", \"\ud83c\uddfa\ud83c\uddfe: uy, ury, Uruguay, SOUTHAMERICA\" },\n  { \"\ud83c\uddfb\ud83c\uddea\", \"\ud83c\uddfb\ud83c\uddea: ve, ven, Venezuela, SOUTHAMERICA\" },\n\n  { \"\ud83c\udde6\ud83c\uddea\", \"\ud83c\udde6\ud83c\uddea: ae, are, UnitedArabEmirates, WESTASIA, ASIA, EURASIA\" }, \/\/ United Arab Emirates\n  { \"\ud83c\udde6\ud83c\uddeb\", \"\ud83c\udde6\ud83c\uddeb: af, afg, Afghanistan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udde9\", \"\ud83c\udde7\ud83c\udde9: bd, bgd, Bangladesh, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\udded\", \"\ud83c\udde7\ud83c\udded: bh, bhr, Bahrain, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddf3\", \"\ud83c\udde7\ud83c\uddf3: bn, brn, Brunei, ASIA, EURASIA\" },\n  { \"\ud83c\udde7\ud83c\uddf9\", \"\ud83c\udde7\ud83c\uddf9: bt, btn, Bhutan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\udde8\ud83c\uddf3\", \"\ud83c\udde8\ud83c\uddf3: cn, chn, China, EASTASIA, ASIA, EURASIA, BRICS\" },\n  { \"\ud83c\udded\ud83c\uddf0\", \"\ud83c\udded\ud83c\uddf0: hk, hkg, HongKong, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\udde9\", \"\ud83c\uddee\ud83c\udde9: id, idn, Indonesia, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf1\", \"\ud83c\uddee\ud83c\uddf1: il, isr, Israel, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf3\", \"\ud83c\uddee\ud83c\uddf3: in, ind, India, SOUTHASIA, ASIA, EURASIA, BRICS\" },\n  { \"\ud83c\uddee\ud83c\uddf6\", \"\ud83c\uddee\ud83c\uddf6: iq, irq, Iraq, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddee\ud83c\uddf7\", \"\ud83c\uddee\ud83c\uddf7: ir, irn, Iran, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddef\ud83c\uddf4\", \"\ud83c\uddef\ud83c\uddf4: jo, jor, Jordan, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddef\ud83c\uddf5\", \"\ud83c\uddef\ud83c\uddf5: jp, jpn, Japan, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddec\", \"\ud83c\uddf0\ud83c\uddec: kg, kgz, Kyrgyzstan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\udded\", \"\ud83c\uddf0\ud83c\udded: kh, khm, Cambodia, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddf7\", \"\ud83c\uddf0\ud83c\uddf7: kr, kor, SouthKorea, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddfc\", \"\ud83c\uddf0\ud83c\uddfc: kw, kwt, Kuwait, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\udde6\", \"\ud83c\uddf1\ud83c\udde6: la, lao, Laos, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\udde7\", \"\ud83c\uddf1\ud83c\udde7: lb, lbn, Lebanon, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddf0\", \"\ud83c\uddf1\ud83c\uddf0: lk, lka, SriLanka, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf3\", \"\ud83c\uddf2\ud83c\uddf3: mn, mng, Mongolia, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf4\", \"\ud83c\uddf2\ud83c\uddf4: mo, mac, Macao, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddfb\", \"\ud83c\uddf2\ud83c\uddfb: mv, mdv, Maldives, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddf2\", \"\ud83c\uddf2\ud83c\uddf2: mm, mmr, Myanmar, ASIA, EURASIA\" },\n  { \"\ud83c\uddf2\ud83c\uddfe\", \"\ud83c\uddf2\ud83c\uddfe: my, mys, Malaysia, ASIA, EURASIA\" },\n  { \"\ud83c\uddf0\ud83c\uddf5\", \"\ud83c\uddf0\ud83c\uddf5: kp, prk, NorthKorea, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf5\", \"\ud83c\uddf3\ud83c\uddf5: np, npl, Nepal, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf4\ud83c\uddf2\", \"\ud83c\uddf4\ud83c\uddf2: om, omn, Oman, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\udded\", \"\ud83c\uddf5\ud83c\udded: ph, phl, Philippines, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf0\", \"\ud83c\uddf5\ud83c\uddf0: pk, pak, Pakistan, SOUTHASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf5\ud83c\uddf8\", \"\ud83c\uddf5\ud83c\uddf8: ps, pse, Palestine, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf6\ud83c\udde6\", \"\ud83c\uddf6\ud83c\udde6: qa, qat, Qatar, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\udde6\", \"\ud83c\uddf8\ud83c\udde6: sa, sau, SaudiArabia, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddec\", \"\ud83c\uddf8\ud83c\uddec: sg, sgb, Singapore, ASIA, EURASIA\" },\n  { \"\ud83c\uddf8\ud83c\uddfe\", \"\ud83c\uddf8\ud83c\uddfe: sy, syr, Syria, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\udded\", \"\ud83c\uddf9\ud83c\udded: th, tha, Thailand, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddef\", \"\ud83c\uddf9\ud83c\uddef: tj, tjk, Tajikistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf1\", \"\ud83c\uddf9\ud83c\uddf1: tl, tls, EastTimor, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf2\", \"\ud83c\uddf9\ud83c\uddf2: tm, tkm, Turkmenistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf9\ud83c\uddfc\", \"\ud83c\uddf9\ud83c\uddfc: tw, twn, Taiwan, EASTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddfa\ud83c\uddff\", \"\ud83c\uddfa\ud83c\uddff: uz, uzb, Uzbekistan, CENTRALASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddfb\ud83c\uddf3\", \"\ud83c\uddfb\ud83c\uddf3: vn, vnm, Vietnam, ASIA, EURASIA\" },\n  { \"\ud83c\uddfe\ud83c\uddea\", \"\ud83c\uddfe\ud83c\uddea: ye, yem, Yemen, WESTASIA, ASIA, EURASIA\" },\n\n  { \"\ud83c\uddf3\ud83c\uddea\", \"\ud83c\uddf3\ud83c\uddea: ne, ner, Nigeria, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf9\", \"\ud83c\uddea\ud83c\uddf9: et, eth, Ethiopia, AFRICA, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf7\", \"\ud83c\uddea\ud83c\uddf7: er, eri, Eritrea, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddec\", \"\ud83c\udde8\ud83c\uddec: cg, cog, Congo, AFRICA, CENTRALAFRICA\" }, \/\/ Rebublic of the Congo\n  { \"\ud83c\udde8\ud83c\udde9\", \"\ud83c\udde8\ud83c\udde9: cd, cod, DemocraticCongo, AFRICA, CENTRALAFRICA\" }, \/\/ Democratic Rebublic of the Congo\n  { \"\ud83c\uddf9\ud83c\uddff\", \"\ud83c\uddf9\ud83c\uddff: tz, tza, Tanzania, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\udde6\", \"\ud83c\uddff\ud83c\udde6: za, zaf, SouthAfrica, AFRICA, SOUTHAFRICA, BRICS\" },\n  { \"\ud83c\uddf0\ud83c\uddea\", \"\ud83c\uddf0\ud83c\uddea: ke, ken, Kenya, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddfa\ud83c\uddec\", \"\ud83c\uddfa\ud83c\uddec: ug, uga, Uganda, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf8\", \"\ud83c\uddf8\ud83c\uddf8: ss, ssd, SouthSudan, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\udde9\", \"\ud83c\uddf8\ud83c\udde9: sd, sdn, Sudan, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde9\ud83c\uddff\", \"\ud83c\udde9\ud83c\uddff: dz, dza, Algeria, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddec\", \"\ud83c\uddea\ud83c\uddec: eg, egy, Egypt, AFRICA, NORTHAFRICA, WESTASIA, ASIA, EURASIA\" },\n  { \"\ud83c\uddf1\ud83c\uddfe\", \"\ud83c\uddf1\ud83c\uddfe: ly, lby, Libya, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf1\ud83c\uddfe\", \"\ud83c\uddf1\ud83c\uddfe: ly, lby, Madeira, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\udde6\", \"\ud83c\uddf2\ud83c\udde6: ma, mar, Morocco, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\udde6\ud83c\uddf4\", \"\ud83c\udde6\ud83c\uddf4: ao, ago, Angola, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddec\ud83c\udded\", \"\ud83c\uddec\ud83c\udded: gh, gha, Ghana, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddff\", \"\ud83c\uddf2\ud83c\uddff: mz, moz, Mozambique, AFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddec\", \"\ud83c\uddf2\ud83c\uddec: mg, mdg, Madagascar, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddfe\ud83c\uddf9\", \"\ud83c\uddfe\ud83c\uddf9: yt, myt, Mayotte, FRANCE, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddee\", \"\ud83c\udde8\ud83c\uddee: ci, civ, IvoryCoast, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddf2\", \"\ud83c\udde8\ud83c\uddf2: cm, cmr, Cameroon, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf3\ud83c\uddea\", \"\ud83c\uddf3\ud83c\uddea: ne, ner, Niger, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddeb\", \"\ud83c\udde7\ud83c\uddeb: bf, bfa, BurkinaFaso, AFRICA, WESTAFRICA\" }, \/\/ Burkina Faso\n  { \"\ud83c\uddf2\ud83c\uddf1\", \"\ud83c\uddf2\ud83c\uddf1: ml, mli, Mali, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfc\", \"\ud83c\uddf2\ud83c\uddfc: mw, mwi, Malawi, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\uddf2\", \"\ud83c\uddff\ud83c\uddf2: zm, zmb, Zambia, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\udde9\", \"\ud83c\uddf9\ud83c\udde9: td, tcd, Chad, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf4\", \"\ud83c\uddf8\ud83c\uddf4: so, som, Somalia, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf3\", \"\ud83c\uddf8\ud83c\uddf3: sn, sen, Senegal, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddff\ud83c\uddfc\", \"\ud83c\uddff\ud83c\uddfc: zw, zwe, Zimbabwe, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddf3\", \"\ud83c\uddec\ud83c\uddf3: gn, gin, Guinea, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf7\ud83c\uddea\", \"\ud83c\uddf7\ud83c\uddea: re, reu, R\u00e9union, reunion, FRANCE, AFRICA, EASTAFRICA\" }, \/\/ R\u00e9union\n  { \"\ud83c\uddf7\ud83c\uddfc\", \"\ud83c\uddf7\ud83c\uddfc: rw, rwa, Rwanda, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddef\", \"\ud83c\udde7\ud83c\uddef: bj, ben, Benin, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddee\", \"\ud83c\udde7\ud83c\uddee: bi, bdi, Burundi, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\uddf3\", \"\ud83c\uddf9\ud83c\uddf3: tn, tun, Tunisia, AFRICA, NORTHAFRICA\" },\n  { \"\ud83c\uddf9\ud83c\uddec\", \"\ud83c\uddf9\ud83c\uddec: tg, tgo, Togo, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddf1\", \"\ud83c\uddf8\ud83c\uddf1: sl, sle, SierraLeone, AFRICA, WESTAFRICA\" }, \/\/ Sierra Leone\n  { \"\ud83c\udde8\ud83c\udde9\", \"\ud83c\udde8\ud83c\udde9: cd, cod, Congo, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddeb\", \"\ud83c\udde8\ud83c\uddeb: cf, caf, CentralAfrican, CENTRALAFRICA\" }, \/\/ Central African Republic\n  { \"\ud83c\uddf1\ud83c\uddf7\", \"\ud83c\uddf1\ud83c\uddf7: lr, lbr, Liberia, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddf7\", \"\ud83c\uddf2\ud83c\uddf7: mr, mrt, Mauritania, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\uddf7\", \"\ud83c\uddea\ud83c\uddf7: er, eri, Eritrea, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddf2\", \"\ud83c\uddec\ud83c\uddf2: gm, gmb, Gambia, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\udde7\ud83c\uddfc\", \"\ud83c\udde7\ud83c\uddfc: bw, bwa, Botswana, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddf3\ud83c\udde6\", \"\ud83c\uddf3\ud83c\udde6: na, nam, Namibia, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddec\ud83c\udde6\", \"\ud83c\uddec\ud83c\udde6: ga, gab, Gabon, AFRICA, CENTRALAFRICA\" },\n  { \"\ud83c\uddf1\ud83c\uddf8\", \"\ud83c\uddf1\ud83c\uddf8: ls, lso, Lesotho, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\uddec\ud83c\uddfc\", \"\ud83c\uddec\ud83c\uddfc: gw, gnb, GuineaBissau, AFRICA, WESTAFRICA\" }, \/\/ Guinea-Bissau\n  { \"\ud83c\uddec\ud83c\uddf6\", \"\ud83c\uddec\ud83c\uddf6: gq, gnq, EquatorialGuinea, CENTRALAFRICA\" }, \/\/ Equatorial Guinea\n  { \"\ud83c\uddf2\ud83c\uddfa\", \"\ud83c\uddf2\ud83c\uddfa: mu, mus, Mauritius, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf2\ud83c\uddfa\", \"\ud83c\uddf2\ud83c\uddfa: mz, moz, Mozambique, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf8\ud83c\uddff\", \"\ud83c\uddf8\ud83c\uddff: sz, swz, Eswatini, AFRICA, SOUTHAFRICA\" },\n  { \"\ud83c\udde9\ud83c\uddef\", \"\ud83c\udde9\ud83c\uddef: dj, dji, Djibouti, AFRICA, EASTAFRICA\" },\n  { \"\ud83c\uddf0\ud83c\uddf2\", \"\ud83c\uddf0\ud83c\uddf2: km, com, Comoros, AFRICA\" },\n  { \"\ud83c\udde8\ud83c\uddfb\", \"\ud83c\udde8\ud83c\uddfb: cv, cpv, CapeVerde, AFRICA, WESTAFRICA\" },\n  { \"\ud83c\uddea\ud83c\udded\", \"\ud83c\uddea\ud83c\udded: eh, esh, WesternSahara, SPAIN, AFRICA, NORTHAFRICA\" }, \/\/ Western Sahara\n  { \"\ud83c\uddf8\ud83c\uddf9\", \"\ud83c\uddf8\ud83c\uddf9: st, stp, S\u00e3oTom\u00e9andPr\u00edncipe, saotomeandprincipe, CENTRALAFRICA\" }, \/\/ S\u00e3o Tom\u00e9 and Pr\u00edncipe\n  { \"\ud83c\uddf8\ud83c\udde8\", \"\ud83c\uddf8\ud83c\udde8: sc, syc, Seychelles, AFRICA, EASTAFRICA\" },\n\n  { \"\ud83c\uddf8\ud83c\udded\", \"\ud83c\uddf8\ud83c\udded: sh, shn, TristandaCunha, UK\" }, \/\/ Tristan da Cunha\n  \n  { \"\ud83c\udde6\ud83c\uddfa\", \"\ud83c\udde6\ud83c\uddfa: au, aus, Australia, AUSTRALASIA, OCEANIA\" },\n  { \"\ud83c\udde8\ud83c\uddfd\", \"\ud83c\udde8\ud83c\uddfd: cx, cxr, Christmasisland, AUSTRALIA\" }, \/\/ Christmas Island\n\n  { \"\ud83c\udde8\ud83c\udde8\", \"\ud83c\udde8\ud83c\udde8: cc, cck, CocosIslands, AUSTRALIA\" }, \/\/ Cocos (Keeling) Islands\n  \n  { \"\ud83c\uddee\ud83c\uddf2\", \"\ud83c\uddee\ud83c\uddf2: im, imn, ManIsle, UK\" }, \/\/ Isle of Man\n  \n  { \"\ud83c\uddf0\ud83c\uddee\", \"\ud83c\uddf0\ud83c\uddee: ki, kir, Kiribati, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf3\ud83c\uddf7\", \"\ud83c\uddf3\ud83c\uddf7: nr, nru, Nauru, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf3\ud83c\udde8\", \"\ud83c\uddf3\ud83c\udde8: nc, ncl, NewCaledonia, FRANCE, OCEANIA\" }, \/\/ New Caledonia\n  { \"\ud83c\uddeb\ud83c\uddef\", \"\ud83c\uddeb\ud83c\uddef: fj, fji, Fiji, MELANESIA, OCEANIA\" },\n  { \"\ud83c\uddeb\ud83c\uddf2\", \"\ud83c\uddeb\ud83c\uddf2: fm, fsm, Micronesia, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf5\ud83c\uddec\", \"\ud83c\uddf5\ud83c\uddec: pg, png, PapuanewGuinea, MELANESIA, OCEANIA\" }, \/\/ Papua New Guinea\n  { \"\ud83c\uddfb\ud83c\uddfa\", \"\ud83c\uddfb\ud83c\uddfa: vu, vut, Vanuatu, MELANESIA, OCEANIA\" },\n  { \"\ud83c\uddf8\ud83c\udde7\", \"\ud83c\uddf8\ud83c\udde7: sb, slb, SolomonIslands, MELANESIA, OCEANIA\" }, \/\/ Solomon Islands\n  { \"\ud83c\uddec\ud83c\uddfa\", \"\ud83c\uddec\ud83c\uddfa: gu, gum, Guam, USA, MICRONESIA, OCEANIA\" },\n  { \"\ud83c\uddf2\ud83c\udded\", \"\ud83c\uddf2\ud83c\udded: mh, mhl, MarshallIslands, MICRONESIA, OCEANIA\" }, \/\/ Marshall Islands\n  { \"\ud83c\uddf2\ud83c\uddf5\", \"\ud83c\uddf2\ud83c\uddf5: mp, mnp, NorthernMariana, MICRONESIA, OCEANIA\" }, \/\/ Northern Mariana Islands\n  { \"\ud83c\uddf5\ud83c\uddeb\", \"\ud83c\uddf5\ud83c\uddeb: pf, pyf, FrenchPolynesia, FRANCE, POLYNESIA, OCEANIA\" }, \/\/ French Polynesia\n  { \"\ud83c\uddfc\ud83c\uddf8\", \"\ud83c\uddfc\ud83c\uddf8: ws, wsm, Samoa, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddfc\ud83c\uddeb\", \"\ud83c\uddfc\ud83c\uddeb: wf, wlf, WallisandFutuna, FRANCE, OCEANIA\" }, \/\/ Wallis and Futuna\n  { \"\ud83c\uddf9\ud83c\uddfb\", \"\ud83c\uddf9\ud83c\uddfb: tv, tuv, Tuvalu, OCEANIA\" },\n  { \"\ud83c\udde6\ud83c\uddf8\", \"\ud83c\udde6\ud83c\uddf8: as, asm, Americansamoa, USA, POLYNESIA, OCEANIA\" }, \/\/ American Samoa\n  { \"\ud83c\uddf5\ud83c\uddf3\", \"\ud83c\uddf5\ud83c\uddf3: pn, pcn, Pitcairn, UK, POLYNESIA, OCEANIA\" }, \/\/ Pitcairn Islands\n  { \"\ud83c\uddf5\ud83c\uddfc\", \"\ud83c\uddf5\ud83c\uddfc: pw, plw, Palau, MICRONESIA, OCEANIA\" },\n\n  { \"\ud83c\uddef\ud83c\uddea\", \"\ud83c\uddef\ud83c\uddea: je, jey, Jersey, FRANCE\" },\n  \n  { \"\ud83c\udde6\ud83c\uddf6\", \"\ud83c\udde6\ud83c\uddf6: aq, ata, Antarctica, ANTARCTICA\" },\n\n  { \"\ud83c\uddf3\ud83c\uddeb\", \"\ud83c\uddf3\ud83c\uddeb: nf, nfk, NorFolkIsland, AUSTRALASIA, POLYNESIA, OCEANIA\" }, \/\/ Norfolk Island\n  { \"\ud83c\udde8\ud83c\uddf0\", \"\ud83c\udde8\ud83c\uddf0: ck, cok, Cookisland, NEWZEALAND, POLYNESIA, OCEANIA\" }, \/\/ Cook Islands\n  { \"\ud83c\uddf3\ud83c\uddff\", \"\ud83c\uddf3\ud83c\uddff: nz, nzl, NewZealand, NEWZEALAND, AUSTRALASIA, OCEANIA\" }, \/\/ New Zealand\n  { \"\ud83c\uddf3\ud83c\uddfa\", \"\ud83c\uddf3\ud83c\uddfa: nu, niu, Niue, NEWZEALAND, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf0\", \"\ud83c\uddf9\ud83c\uddf0: tk, tkl, Tokelau, NEWZEALAND, POLYNESIA, OCEANIA\" },\n  { \"\ud83c\uddf9\ud83c\uddf4\", \"\ud83c\uddf9\ud83c\uddf4: to, ton, Tonga, POLYNESIA, OCEANIA\" },\n  \n  \/\/ still missing\n  \n  { \"\ud83c\uddee\ud83c\uddf4\", \"\ud83c\uddee\ud83c\uddf4: io, iot, BritishIndianOcean\" }, \/\/ British Indian Ocean Territory\n  { \"\ud83c\uddf9\ud83c\uddeb\", \"\ud83c\uddf9\ud83c\uddeb: tf, atf, FrenchSouthernandaAtarctic\" }, \/\/ French Southern and Antarctic Lands\n  { \"\ud83c\uddec\ud83c\uddec\", \"\ud83c\uddec\ud83c\uddec: gg, ggy, Guernsey, GUERNSEY\" },\n  { \"\ud83c\udded\ud83c\uddf2\", \"\ud83c\udded\ud83c\uddf2: hm, hmd, HeardandMacDonaldsIslands\" }, \/\/ Heard Island and McDonald Islands\n  { \"\ud83c\uddfa\ud83c\uddf2\", \"\ud83c\uddfa\ud83c\uddf2: um, umi, UsMinorOutlyingIslands, US\" }, \/\/ United States Minor Outlying Islands\n};\n\n\/*\n *  flags changed\n *\/\nstatic int flagidflags = 0; \/\/ dont display ids\n\nstatic int idsall = 1;\n\n\/*\n *  flag for each id\n *\/\nstatic char flagids&#91;sizeof(idsflags) \/ sizeof(idsflags&#91;0])];\n\nint newressu_toggleflag(unsigned char *flag)\n{\n  int c, ok;\n  \n  if(!strcmp(flag, \"ALL\")) {\n    idsall = !idsall;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      flagids&#91;c] = idsall;\n    }\n    flagidflags = 1; \/\/ display flags\n    ok = 1; \/\/ one flag toggled\n  } else {\n    ok = 0;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      if(newressu_strstr(idsflags&#91;c].flags, flag)!=NULL) {\n\tflagids&#91;c] = !flagids&#91;c];\n\tflagidflags = 1; \/\/ display flags\n\tok = 1; \/\/ one flag toggled\n      }\n    }\n    \/\/if(ok)\n    \/\/  fprintf(stdout,\"\\n\");\n  }\n  return(ok);\n}\n\n#ifdef FORT\n#include \"fort.h\"\n#endif\n\nvoid clock_bytes(int size, unsigned char *buffer) \/\/ JariK 2024\n{\n  int c;\n  \n  for(c = 0; c &lt; size; c++)\n    buffer&#91;c] = ressu_clock();\n}\n\nstatic unsigned char samplefilename&#91;128] = \"newressusample%d.rnd\";\n\nint input = INPUT_RESSU;\nunsigned char *input_str = \"ressu\";\n\nint base = -1;\n\nstatic unsigned char newressutab&#91;GENT_SIZE]; \/\/ orig 1024 \nstatic unsigned int newressutab_pos = 0;\n\nvoid newressu_clear()\n{\n  memset(newressutab, 0, sizeof(newressutab)); \/\/ forget newressutab\n}\n\n#define aDEBUG18 2\n\nint newressu_genbyte()\n{\n  unsigned char ch;\n\n  if(newressutab_pos == 0) {\n#ifdef DEBUG23\n    ressu_dump(\"oldgent\", 32, newressutab, 32); \/\/ first 32 bytes\n#endif\n\n    newressu_clear();\n    \n    if(input == INPUT_RESSU) \/\/ ressu prod\n      ressu_genbytes(sizeof(newressutab), newressutab);\n\n#ifdef SHA256\n    else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n      pseudoressu_bytes(sizeof(newressutab), newressutab);\n    \n#endif\n#ifdef SHA256\n    else if(input == INPUT_RESSUTWIST) \/\/ ressu w twist\n      ressutwist_bytes(sizeof(newressutab), newressutab);\n\n#endif\n    else if(input == INPUT_FASTRESSU) \/\/ ressu_fast\n      ressu_genbytes_fast(sizeof(newressutab), newressutab);\n\n    else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n      ressu_genbytes_single(sizeof(newressutab), newressutab);\n\n    else if(input == INPUT_STREAM) \/\/ stream\n      stream_bytes(sizeof(newressutab), newressutab);\n\n    else if(input == INPUT_TEST) \/\/ test generator\n      test_bytes(sizeof(newressutab), newressutab);\n\n#ifdef FORT\n    else if(input == INPUT_FORT) \/\/ ressu fort\n      fort_random_data(sizeof(newressutab), newressutab);\n\n    else if(input == INPUT_FORTXOR) \/\/ ressu fort\n      fort_random_data_xor(sizeof(newressutab), newressutab);\n\n#endif\n#ifdef USE_RDRAND\n    else if(input == INPUT_RDRAND) \/\/ intel rdrand\n      rdrand_bytes(sizeof(newressutab), newressutab);\n\n#endif\n#ifdef USE_RDSEED\n    else if(input == INPUT_RDSEED) \/\/ intel rdseed\n      rdseed_bytes(sizeof(newressutab), newressutab);\n\n#endif\n    else if(input == INPUT_URANDOM) \/\/ urandom\n      urandom_bytes(sizeof(newressutab), newressutab);\n\n#ifdef USE_RANDOM\n    else if(input == INPUT_RANDOM) \/\/ random\n      random_bytes(sizeof(newressutab), newressutab);\n\n#endif\n    else if(input == INPUT_CLOCK) \/\/ clockstream\n      clock_bytes(sizeof(newressutab), newressutab);\n\n    else {\n      fprintf(stdout,\"%s: mode '%d'(%s) not available\\n\",\n\t      procname, input, input_str);\n      exit(2);\n    }\n#ifdef DEBUG23\n    ressu_dump(\"newgent\", 32, newressutab, 32); \/\/ first 32 bytes\n#endif\n  } \/\/ if(newressutab_pos==0\n  ch = newressutab&#91;newressutab_pos];\n  newressutab_pos = (newressutab_pos + 1) % sizeof(newressutab);\n\n#ifdef DEBUG18\n  fprintf(stdout, \"{%02x}\", ch);\n#endif\n  return(ch);\n}\n\nstatic unsigned char *basedigits = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-\"; \/\/ 64 chars\n\nvoid fprintfbase(FILE *fp1, unsigned long long ll2, int base) \/\/ JariK 2023\n{\n  int count;\n  unsigned long long ll, divider;\n\n  if(base == 2)\n    fprintf(fp1,\"0b\");\n  else if(base == 8)\n    fprintf(fp1,\"0o\");\n  else if(base == 10)\n    fprintf(fp1,\"0d\");\n  else if(base == 16)\n    fprintf(fp1,\"0x\");\n  \n  ll = ll2;\n  divider = 1;\n  count = 0;\n\n  for(;;) { \/\/ count digits\n    ll \/= base;\n    count++;\n    if(ll == 0)\n      break;\n    divider *= base; \/\/ do not count last digit\n  }\n\n  while(count > 0) { \/\/ print digits\n    fprintf(fp1,\"%c\", basedigits&#91;(ll2 \/ divider) % base]);\n    divider \/= base;\n    count--;\n  }\n}\n\n#define aDEBUG24 2\n  \nunsigned long newressu_gen_limit(unsigned long limit) \/\/ JariK 2022\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n\n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) { \/\/ one byte\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n\n    } else if(limit &lt;= 0x10000) { \/\/ two bytes\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n\n    } else if(limit &lt;= 0x1000000) { \/\/ three bytes\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n\n    } else if(limit &lt;= 0x100000000) { \/\/ four bytes\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n\n    } else if(limit &lt;= 0x10000000000) { \/\/ five bytes\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n\n    } else if(limit &lt;= 0x1000000000000) { \/\/ six bytes\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n\n    } else if(limit &lt;= 0x100000000000000) { \/\/ seven bytes\n      highlimit = (0x100000000000000 \/ limit) * limit;      \n      bytes = 7;\n\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n\n    }\n  } \/\/ if(lastlimit != limit\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | newressu_genbyte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n#define aDEBUG34\n\n#ifdef DEBUG34\n  fprintf(stdout,\"limit:%lu\", limit);\n  fprintf(stdout,\", highlimit:%lu\", highlimit);\n  fprintf(stdout,\", bytes:%d\", bytes);\n  fprintf(stdout,\", word:%lu\", word);\n  fprintf(stdout,\", word%%limit:%lu\", (unsigned long) word % limit);\n  fprintf(stdout,\", base:\");\n  if(base == -1)\n    fprintfbase(stdout, word % limit, 16);\n  else\n    fprintfbase(stdout, word % limit, base);\n  fprintf(stdout,\", base:0o%lo\", word % limit);\n  fprintf(stdout,\", base:0d%lu\", word % limit);\n  fprintf(stdout,\", base:0x%lx\", word % limit);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  word %= limit;\n  \n#ifdef DEBUG24\n  fprintf(stdout,\"\/\");\n  fprintf(stdout,\"%d bytes: \", bytes);\n  fprintf(stdout,\"&#91;\");\n  if(base == -1)\n    fprintfbase(stdout, word, 16);\n  else\n    fprintfbase(stdout, word, base);\n  fprintf(stdout,\"]\");\n  fprintf(stdout,\"\/\");\n  fflush(stdout);\n#endif\n\n  return(word);\n}\n\nstatic int cursor_on = 0;\nunsigned char cursor&#91;4] = { '|', '\/', '-', '\\\\' };\nlong int prev_secs = -1;\nint crs = 0;\n\nvoid stat_line_cursor_start()\n{\n  fprintf(stderr,\"%c\", cursor&#91;crs]);\n  fflush(stderr);\n  \/\/prev_secs = -1;\n  cursor_on = 1;\n}\n\nvoid stat_line_cursor()\n{\n  long int secs;\n\n  secs = time(NULL) % sizeof(cursor);\n  if(prev_secs != secs) {\n    if(prev_secs != -1) \n      crs = (crs + 1) % sizeof(cursor);\n    fprintf(stderr,\"\\b%c\", cursor&#91;crs]);\n    fflush(stderr);\n    prev_secs = secs;\n  }\n}\n\nvoid stat_line_cursor_remove()\n{\n  if(cursor_on) {\n    fprintf(stderr, \"\\b \\b\");\n    fflush(stderr);\n    \/\/prev_secs = -1;\n  }\n  cursor_on = 0;\n}\n\n#include &lt;stdarg.h>\n\n#define aDEBUG31 2\n\nunsigned char *procname = NULL;\n\nstatic unsigned char *prev_stat_line = NULL;\nstatic unsigned char *stat_line = NULL;\nstatic size_t stat_line_length = 0;\n\nstatic void stat_line_begin()\n{\n  if(stat_line != NULL)\n    stat_line&#91;0] = '\\0';\n}\n\nstatic void stat_line_printf(const unsigned char *format, ...)\n{\n  int count;\n  va_list args;\n  static unsigned char *buffer = NULL;\n  static size_t buffer_length = 0;\n\n  va_start(args, format);\n  count = vsnprintf(buffer, buffer_length, format, args) + 1;\n  va_end(args);\n\n  if(buffer_length &lt; count) {\n    buffer_length = count;\n    buffer = realloc(buffer, buffer_length);\n    va_start(args, format);\n    count = vsnprintf(buffer, buffer_length, format, args) + 1;\n    va_end(args);\n  }\n\n  count = 0;\n  if(stat_line != NULL)\n    count += strlen(stat_line);\n  count += strlen(buffer);\n  count++;\n  \n  if(stat_line_length &lt; count) {\n    unsigned char *stat_line2 = stat_line;\n    stat_line_length = count;\n    stat_line = realloc(stat_line, stat_line_length);\n    prev_stat_line = realloc(prev_stat_line, stat_line_length);\n    if(stat_line2 == NULL) {\n      stat_line&#91;0] = '\\0';\n      prev_stat_line&#91;0] = '\\0';\n    }\n  }\n  strcat(stat_line, buffer);\n}\n\n#define READABLE_NUMBER_BIN 2\n\n#ifdef READABLE_NUMBER_BIN\n#define READABLE_NUMBER_HIGH 1023\n#define READABLE_NUMBER_DIVIDER 1024\n#else\n#define READABLE_NUMBER_HIGH 999\n#define READABLE_NUMBER_DIVIDER 1000\n#endif\n\n#define READABLE_NUMBER_WIDTH 32\n\nstatic void stat_line_get_readable(unsigned char buf10&#91;10], unsigned long long length)\n{\n  int c, low;\n  double length2;\n\n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  strcpy(buf10, \"***\");\n  low = 0;\n\n  for(c = 0; length >= low &amp;&amp;\n      c &lt; sizeof(units) - 1; c++) {\n    if(length >= low &amp;&amp;\n       length &lt;= READABLE_NUMBER_HIGH) {\n      if(units&#91;c] == 'B')\n        sprintf(buf10, \"%lld\", length);\n      else if(units&#91;c] == 'K' ||\n\t      units&#91;c] == 'M' ||\n\t      units&#91;c] == 'G' ||\n\t      units&#91;c] == 'T')\n\tsprintf(buf10, \"%.3f\", length2);\n      else if(length == length2)\n\tsprintf(buf10, \"%lld\", length);\n      else\n\tsprintf(buf10, \"%.1f\", length2);\n\n      if(strchr(buf10, '.') != NULL) {\n\tint d;\n\td = strlen(buf10) - 1;\n\twhile(d > 3 &amp;&amp; isdigit(buf10&#91;d])) {\n\t  buf10&#91;d] = '\\0';\n\t  d--;\n\t}\n\tif(buf10&#91;strlen(buf10)-1] == '.')\n\t  buf10&#91;strlen(buf10)-1] = '\\0';\n      }\n\n      if(units&#91;c] != 'B') {\n\tchar unit&#91;10];\n\tsprintf(unit,\"%cB\",units&#91;c]);\n\tstrcat(buf10, unit);\n      }\n      break;\n    }\n    length2 = (double)length \/ READABLE_NUMBER_DIVIDER;\n    length \/= READABLE_NUMBER_DIVIDER;\n    low = 1;\n  }\n}\n\nstatic void stat_line_readable(unsigned long long length)\n{\n  unsigned char buf10&#91;10];\n  stat_line_get_readable(buf10, length);\n  stat_line_printf(\"%s\", buf10);\n}\n\nstatic void stat_line_dhms(unsigned long long printleft)\n{\n  unsigned long int left2;\n  unsigned long int temp;\n  int timeprinted = 0;\n  \n  left2 = printleft;\n  temp = left2 \/ (24 * 3600); \/\/ days\n  if(temp > 0) {\n    timeprinted = 1;\n    stat_line_printf(\" %dd\", temp);\n    left2 -= temp * (24 * 3600);\n  }\n  \n  temp = left2 \/ 3600; \/\/ hours\n  if(temp > 0 || timeprinted) {\n    timeprinted = 1;\n    \/\/hoursprinted = 1;\n    stat_line_printf(\" %02dh\", temp);\n    left2 -= temp * 3600;\n  }\n  \n  temp = left2 \/ 60; \/\/ minutes\n  if(temp > 0 || timeprinted) {\n    timeprinted = 1;\n    stat_line_printf(\" %02dm\", temp);\n    left2 -= temp * 60;\n  }\n  \n  temp = left2; \/\/ seconds\n  if(!timeprinted) {\n    stat_line_printf(\" %d seconds\", temp);\n  }\n  \n}\n\nvoid stat_line_end()\n{\n  int c, d;\n\n  if(stat_line != NULL &amp;&amp; strcmp(prev_stat_line, stat_line)) { \/\/ status line changed\n    stat_line_cursor_remove();\n#ifdef DEBUG31\n    fprintf(stderr, \"\\n\");\n#else\n    fprintf(stderr, \"\\r\");\n#endif  \n\n    fprintf(stderr,\"%s\", stat_line);\n    fflush(stderr);\n\n    \/\/ previous line longer than this one,\n    \/\/ overwrite with spaces and backspace to\n    \/\/ end\n    \n    d = strlen(prev_stat_line) - strlen(stat_line) + 1; \/\/ cursor too\n\n    if(d > 0) { \/\/ previous line longer\n      for(c = 0; c &lt; d; c++) {\n#ifdef DEBUG31\n\tfprintf(stderr, \"*\");\n#else\n\tfprintf(stderr, \" \"); \/\/ print spaces\n#endif\n      }\n#ifndef DEBUG31\n      for(c = 0; c &lt; d; c++)\n\tfprintf(stderr, \"\\b\"); \/\/ and backspaces\n#endif\n    }\n    strcpy(prev_stat_line, stat_line);\n    \/\/if(strlen(stat_line) > 0)\n    \/\/stat_line_cursor_start();\n    \/\/stat_line_cursor();\n  }\n}\n\n#define KILO 1024\n\nvoid readablelonglong(FILE *fp1, unsigned long long ll2) \/\/ 2023 JariK\n{\n  int c;\n  unsigned long long multiplier, ll = ll2;\n  \n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n\n  char units&#91;] = \"BKMGTPEZY\";\n\n  c = 0;\n  multiplier = 1;\n  while(ll >= KILO) {\n    ll \/= KILO;\n    multiplier *= KILO;\n    c++;\n  }\n\n  if(ll * multiplier != ll2)\n    fprintf(fp1,\"~\"); \/\/ approximately\n\n  fprintf(fp1,\"%llu%c\", ll, units&#91;c]);\n}\n\nvoid fprintfcharacter(FILE *fp1, unsigned char *p) \/\/ 2023 JariK\n{\n  fputc(*p, fp1); \/\/ print first char\n  if(*p > 0xbf) { \/\/ first char utf8\n    p++;\n    for(;;) { \/\/ print rest of the utf8 chars\n      if(*p > 0xbf || \/\/ new utf8 character\n\t *p &lt; 0x80 || \/\/ ascii character\n\t *p == '\\0') \/\/ end of string\n\tbreak;\n      fputc(*p, fp1);\n      p++;\n    }\n  }\n}\n\nint getdigit(unsigned char *p) \/\/ 2023 JariK\n{\n  int digit;\n  \n  if(*p >= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0';\n  else if(*p >= 'a' &amp;&amp; *p &lt;= 'z')\n    digit = (*p - 'a') + 10;\n  else if(*p >= 'A' &amp;&amp; *p &lt;= 'Z')\n    digit = (*p - 'A') + 10;\n  else\n    digit = -1; \/\/ not found, illegal\n\n  return(digit);\n}\n\n#define DEBUG32\n\n\/\/#define KILO 1000\n#define KILO 1024\n\nunsigned long long getlonglong(unsigned char *p2) \/\/ 2023 JariK\n{\n  int digit, base = 10;\n  unsigned char *p = p2;\n  unsigned long long totll, ll, prevll, multiplier;\n  \n  totll = 0;\n\n  while(*p != '\\0') { \/\/ works also: 1g100m &amp; 1m20k and 1t1t etc...\n\n    unsigned char *prevp = p;\n    \n    if(!strncmp(\"0x\", p, 2)) {\n      base = 16;\n      p += 2;\n      \n    } else if(!strncmp(\"0d\", p, 2)) {\n      base = 10;\n      p += 2;\n      \n    } else if(!strncmp(\"0o\", p, 2)) {\n      base = 8;\n      p += 2;\n      \n    } else if(!strncmp(\"0b\", p, 2)) {\n      base = 2;\n      p += 2;\n      \n    }\n    \n    ll = 0;\n    while((digit = getdigit(p)) != -1 &amp;&amp; digit &lt; base) {\n      ll = ll * base + digit;\n      p++;\n    }\n    \n    multiplier = 1;\n    \n    if(*p == 'k' || *p == 'K') {\n      multiplier = KILO;\n      p++;\n      \n    } else if(*p == 'm' || *p == 'M') {\n      multiplier = (KILO * KILO);\n      p++;\n      \n    } else if(*p == 'g' || *p == 'G') {\n      multiplier = (KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 't' || *p == 'T') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'p' || *p == 'P') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    } else if(*p == 'e' || *p == 'E') {\n      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);\n      p++;\n      \n    }\n    \n    prevll = ll;\n    ll *= multiplier;\n    if(ll \/ multiplier != prevll) {\n      fflush(stdout);\n      fprintf(stderr,\"%s: multiply overflow\", procname);\n      fprintf(stderr,\", string:'%s'\", p2);\n      fprintf(stderr,\", digit:'\");\n      fprintfcharacter(stderr, p);\n      fprintf(stderr,\"'\");\n      fprintf(stderr,\", value: %d\", digit);\n      fprintf(stderr,\", base: %d\", base);\n      fprintf(stderr,\", ll: %llu\", prevll);\n      fprintf(stderr,\", multiplier: %llu\", multiplier);\n      fprintf(stderr,\"\\n\");\n      fflush(stderr);\n    }\n  \n    if(*p == 'b' || *p == 'B') \/\/ remove last b (for bytes in 1tb, 1gb or 1mb)\n      p++;\n    \n    totll += ll;\n\n#ifdef DEBUG32\n    fprintf(stderr,\"string:'%s'\", p2);\n    fprintf(stderr,\", base:%d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", multiplier:%llu(\", multiplier);\n    readablelonglong(stderr, multiplier);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", prevll:%llu(\", prevll);\n    readablelonglong(stderr, prevll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", ll:%llu(\", ll);\n    readablelonglong(stderr, ll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", totll:%llu(\", totll);\n    readablelonglong(stderr, totll);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n#endif\n    \n    if(prevp == p) \/\/ no progress\n      break;\n  }\n  \n  if(*p != '\\0') {\n    fflush(stdout);\n    fprintf(stderr,\"%s: illegal digit\", procname);\n    fprintf(stderr,\", string:'%s'\", p2);\n    fprintf(stderr,\", digit:'\");\n    fprintfcharacter(stderr, p);\n    fprintf(stderr,\"'\");\n    fprintf(stderr,\", value: %d\", digit);\n    fprintf(stderr,\", base: %d(\", base);\n    readablelonglong(stderr, base);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n\n  return(totll);\n}\n\nstatic int zero = 1, sspace = 0, snewline = 0,\n  scrlf = 1, chars = 72, pchars = 0, charwidth = 1,\n  charspaces = 0, words = 0, pwords = 0, cwords = 0,\n  plinesdigits = 5, slineno = 1, screen = 0,\n  quiet = 0, sort = 0, unique = 0,\n  flagprintdigits = 0;\n\nstatic int calc_spaces()\n{\n  int spaces;\n\n  spaces = 0;\n  \n  if(sspace >= 2 &amp;&amp;\n     \/\/ space between word groups\n     ( (cwords > 0 &amp;&amp; cwords % sspace == 0) ||\n       \/\/ space after linenumber\n       \/\/ are not printed if\n       \/\/ not printing linenumber\n       (slineno &amp;&amp; cwords == 0) ) )\n    spaces++;\n    \n  if(sspace &amp;&amp;\n     \/\/ space between words\n     ( (cwords > 0) ||\n       \/\/ space after linenumber\n       (slineno &amp;&amp; cwords == 0) ) ) \n    spaces++;\n\n  return(spaces);\n}\n\nstatic void print_spaces(char spacechar)\n{\n  int sp;\n\n  for(sp = calc_spaces(); sp > 0; sp--)\n    fputc(spacechar, stdout);\n}\n\nstatic long long lines = 10, plines = 0, ptotallines = 0;\n\nvoid printcolumns(int offset, int base, int startwith, int columns, int *clines) \/\/ 2023 JariK\n{\n  \/\/---------11111111112222222222333333333344444444445555555555666666666677\n  \/\/12345678901234567890123456789012345678901234567890123456789012345678901\n  \/\/=======================================================================\n  \/\/00000 86747100388687087416829400778878989202760594993130062980826178851\n  \/\/00001 36862623069143814543525935285460059703805218323534266522497684582\n  \n  int c, d, digit, nonzero;\n  unsigned char digits&#91;0x10] = \"0123456789abcdef\";\n\n  *clines = 0;\n\n  if(base == 2)\n    c = 1 &lt;&lt; 12;\n  else if(base == 8)\n    c = 01000000;\n  else if(base == 10)\n    c = 1000000;\n  else if(base == 16)\n    c = 0x1000000;\n  else {\n    fprintf(stdout,\"%s: printcolumns():\", procname);\n    fprintf(stdout,\" illegal base %d\", base);\n    fprintf(stdout,\"\\n\");\n    exit(1);\n  }\n\n  for(;c >= 1; c \/= base) { \/\/ lines, 100000's, 10000's, 1000's ... 1's\n    if(c >= columns)\n      continue;\n\n    for(d = 0; d &lt; offset; d++)\n      fprintf(stdout,\" \"); \/\/ spaces in beginning of row\n\n    nonzero = 0;\n    \n    for(d = startwith; d &lt; columns + startwith; d++) { \/\/ column numbers\n      digit = (d \/ c) % base;\n      if(digit != 0)\n\tnonzero = 1;\n      if(nonzero || c == 1)\n\tfprintf(stdout,\"%c\", digits&#91;digit]); \/\/ nonzero digits after first nonzero\n      else\n\tfprintf(stdout,\"-\"); \/\/ zeroes in beginning of row\n    }\n    fprintf(stdout,\"\\n\");\n    (*clines)++;\n  }\n  if(pwords > 0) {\n    if(slineno) {\n      for(c = 0; c &lt;= plinesdigits; c++) \/\/ +1\n\tfprintf(stdout,\"-\");\n    }\n    for(cwords = 0; cwords &lt; pwords; cwords++) {\n      print_spaces('-');\n      fprintf(stdout,\"w\");\n      if(charwidth == 2)\n\tfprintf(stdout,\"-\");\n      for(c = 0; c &lt; size - 1; c++) {\n\tfprintf(stdout,\"-\");\n\tif(charwidth == 2)\n\t  fprintf(stdout,\"-\");\n      }\n    }\n    fprintf(stdout,\"\\n\");\n    (*clines)++;\n  }\n  for(d = 0; d &lt; offset; d++)\n    fprintf(stdout,\" \"); \/\/ spaces in beginning of row\n  for(d = startwith; d &lt; columns + startwith; d++)\n    fprintf(stdout,\"=\");\n  fprintf(stdout,\"\\n\");\n  (*clines)++;\n}\n\n#ifdef SAMPLE_HASH\n\nvoid hashfinal2string(unsigned char *hashstring, unsigned char *final)\n{\n  for(int c = 0; c &lt; HashLen; c++) {\n    sprintf(hashstring + 2 * c, \"%02x\",final&#91;c]);\n  }\n}\n\n#endif\n\nstatic int sample = 0, dieharder = 0; \/\/ randomness analysis\n\n\/\/ try randomness analysis with: $ dieharder -a -g 201 -f newressusample1.rnd > newressusample1.rnd.dieharder\n\n#include &lt;signal.h>\n\ntypedef void (*sighandler_t)(int);\n\nvoid sample_handler()\n{\n  static int times = 0;\n\n  times++;\n\n  fprintf(stderr,\"Ctrl-c pressed %d times\\n\", times);\n  if(times >= 10) {\n    signal(SIGINT, SIG_DFL);\n    exit(2);\n  }\n}\n\n#define DEBUG39\n\n#define FILESIZE 3 * 1024 * 1024 * 1024\n#define BLOCKSIZE 384 * 1024\n#define BLOCKS 8192\n\nunsigned long long filesize = (long long)FILESIZE, blocks = BLOCKS;\nunsigned int blocksize = BLOCKSIZE;\nint filesize_set = 0, blocks_set = 0, blocksize_set = 0;\nint purge = 1;\nint purge_set = 0;\nunsigned char *filesize_str = NULL, *blocks_str = NULL, *blocksize_str = NULL;\n\n\nvoid dump_sample() \/\/ &amp; dieharder analysis\n{\n#define STAT_LINE_SHOW_BLOCK 2 \/\/ on by default\n#define STAT_LINE_SHOW_WRITTEN 2 \/\/ on by default\n#define STAT_LINE_SHOW_SPEED 2 \/\/ on by default\n#define STAT_LINE_SHOW_NOW 2 \/\/ on by default\n#define STAT_LINE_SHOW_LEFT 2 \/\/ on by default\n#define STAT_LINE_SHOW_READY 2 \/\/ on by default\n\n#define STAT_LINE_LESS_WOBBLE 2 \/\/ on by default\n\n#define TIMEFORMAT \"%H:%M %Z\"\n#define TIMEFORMAT2 \"%a %H:%M %Z\"\n#define DATEFORMAT \"%a %d %b %Y\"\n    \n  unsigned long long c;\n  unsigned char *buffer, filename&#91;128], command&#91;1024];\n  \n  FILE *fp1;\n  \n  \/\/ find first available filename,\n  \/\/ or empty \"fileslot\"\n  \n  for(c = 1; c &lt;= 99999; c++) {\n\n    sprintf(filename, samplefilename, c);\n    \n    if((fp1 = fopen(filename, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n\n    unsigned char filename2&#91;138];\n\n    sprintf(filename2,\"%s.dieharder\",filename);\n    if((fp1 = fopen(filename2, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n#ifdef SAMPLE_HASH\n    sprintf(filename2,\"%s.sha256\",filename);\n    if((fp1 = fopen(filename2, \"r\")) != NULL) {\n      fclose(fp1);\n      continue;\n    }\n#endif\n\n    break;\n  }\n\n  \n  \/\/ calculate missing file size parameters\n  \n  if(!filesize_set)\n    filesize = blocks * blocksize;\n  else if(!blocksize_set) {\n    blocksize = (filesize + blocks - 1) \/ blocks; \/\/ round up\n    filesize = blocks * blocksize;\n  } else if(!blocks_set) {\n    blocks = (filesize + blocksize - 1)\/ blocksize; \/\/ round up\n    filesize = blocks * blocksize;\n  }\n\n#define EXFAT_FIX 2 \/\/ on for now\n  \n#ifdef EXFAT_FIX\n\n  if(blocksize > KILO * KILO) { \/\/ max \"blocksize\" 1m (exfat)\n    blocksize = KILO * KILO;\n    blocks = (filesize + blocksize - 1) \/ blocksize;\n    filesize = blocks * blocksize;\n  }\n\n#endif\n  \n  if(filesize != blocks * blocksize ||\n     blocks &lt; 1 || blocksize &lt; 1) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): mismatched parameters\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n  \n  if(filesize \/ blocks != blocksize) {\n    fflush(stdout);\n    fprintf(stderr,\"%s: sample(): parameter overflow\", procname);\n    fprintf(stderr,\", blocks:%llu(\", blocks);\n    readablelonglong(stderr, blocks);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", blocksize:%u(\", blocksize);\n    readablelonglong(stderr, blocksize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\", filesize:%llu(\", filesize);\n    readablelonglong(stderr, filesize);\n    fprintf(stderr,\")\");\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n    exit(1);\n  }\n\n#ifdef DEBUG39\n  fprintf(stderr,\"blocksize:%u(\", blocksize);\n  readablelonglong(stderr, blocksize);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", blocks:%llu(\", blocks);\n  readablelonglong(stderr, blocks);\n  fprintf(stderr,\")\");\n  fprintf(stderr,\", filesize:%llu(\", filesize);\n  readablelonglong(stderr, filesize);\n  fprintf(stderr,\")\\n\");\n  fflush(stderr);\n#endif\n\n  if((buffer = malloc(blocksize)) == NULL) {\n    fprintf(stderr,\"%s: sample(): cannot allocate memory (buffer)\\n\", procname);\n    exit(1);\n  }\n  \n#define DEBUG40 2 \/\/ default on (for now)\n    \n#ifdef DEBUG40\n  fprintf(stderr,\"%s: sample(): writing file\", procname);\n  fprintf(stderr,\", filename:%s\", filename);\n#ifndef SAMPLE_WRITE\n  fprintf(stderr,\", no write\");\n#endif\n  fprintf(stderr,\"\\n\");\n#endif\n  \n#ifdef SAMPLE_HASH\n  unsigned char digest&#91;HashLen];\n  HashCtx hash;\n  \n  HashInit(&amp;hash); \/\/ calculate hash\n#endif\n\n  \/\/ variables for stat line fields\n\n  time_t start, now, left, end, took;\n  unsigned char speed&#91;10], printspeed&#91;10] = \"\";\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n  time_t prevend = -1;\n  int countspeed = 0, countend = 0;\n  unsigned char prevspeed&#91;10] = \"\";\n  unsigned int calculateleft;\n\n#endif\n\n  time_t printleft = -1, printend = -1;\n  int leftprinted = 0;\n\n  unsigned long long clim = 0;\n  \n  if((fp1 = fopen(filename, \"a\")) != NULL) {\n\n    \/\/ starting time\n    \n    start = time(NULL);\n    \n    clim = (unsigned long long) filesize \/ blocksize;\n\n#ifdef EXFAT_FIX\n    int mbinblocks = (1 * KILO * KILO) \/ blocksize;\n    if(mbinblocks == 0)\n      mbinblocks = 1;\n    fprintf(stderr,\"mbinblocks:%d\\n\", mbinblocks);\n#endif\n    \n    \/\/ you have to press ctrl-c 10 times\n\n    signal(SIGINT, sample_handler);\n    \n    for(c = 0; c &lt; clim; c++) {\n\n      \/\/ current time\n      \n      now = time(NULL);\n\n      \/\/ estimate for ending time\n      \n      end = (time_t)start + ((((double)now - start) \/ c) * clim);\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n      calculateleft = 0; \n      if(prevend \/ 60 == end \/ 60 &amp;&amp;\n\t ++countend >= 30) { \/\/ 30 times same minutes --> minutes are real\n\n\tprintend = end;\n\tcalculateleft = 1;\n      } else if(prevend \/ 60 != end \/ 60) { \/\/ minutes different\n\tprevend = end;\n\tcountend = 0;\n      }\n\n#else\n      printend = end;\n#endif\n\n      \/\/ estimate for time left\n\n      left = printend - now;\n\n#ifdef STAT_LINE_LESS_WOBBLE\n      \n      static int onlyseconds = 0;\n      static long long cstart, cleft, cseconds;\n      \n      if(onlyseconds || (left > 0 &amp;&amp; left &lt; 60)) {\n\tif(!onlyseconds) {\n\t  cstart = c;\n\t  cleft = clim - c;\n\t  cseconds = left;\n\t  onlyseconds = 1;\n\t}\n\n\tleft = (double) cseconds - ((((double) c - cstart) \/ cleft) * cseconds);\n      }\n\n      if(calculateleft)\n\tprintleft = left;\n      \n#else\n      printleft = left;\n#endif\n\n      \/\/ speed\n      \n      if(now - start > 1.0)\n\tstat_line_get_readable(speed, (unsigned long long)((double)c * blocksize \/ (now - start)) );\n      else\n\tstat_line_get_readable(speed, (unsigned long long)((double)c * blocksize));\n\n#ifdef STAT_LINE_LESS_WOBBLE\n\n      if(!strcmp(prevspeed, speed) &amp;&amp;\n\t ++countspeed >= 3) { \/\/ three times same speed --> speed is real\n\tstrcpy(printspeed, speed);\n      } else if(strcmp(prevspeed, speed)) {\n\tstrcpy(prevspeed, speed);\n\tcountspeed = 0;\n      }\n\n#else\n      strcpy(printspeed, speed);\n#endif\n      \n      \/\/ print status line:\n      \/\/ blk 10, written 10MB, 269KB\/sec, left 8 h 38 m, ready at Sat 17 Jul 2021 01:57:43 EEST, now Fri 17:19:32 EEST\n      \n      stat_line_begin();\n      \n      int print = 0;\n#ifdef STAT_LINE_SHOW_BLOCK\n      \n      stat_line_printf(\"%s\", input_str);\n      \n      \/\/ print block from 0 to 8192\n      \n      stat_line_printf(\"block %d\", c);\n      print = 1;\n#endif\n      \n#ifdef STAT_LINE_SHOW_WRITTEN\n      \n      \/\/ print written\n      \n      if(print)\n\tstat_line_printf(\", \");\n      \n      stat_line_printf(\"written \");\n      stat_line_readable((unsigned long)c * blocksize);\n      print = 1;\n#endif\t  \n      if(c > 0) {\n\t\n#ifdef STAT_LINE_SHOW_SPEED\n\t\n\t\/\/ print speed\n\t\n\tif(printspeed&#91;0] != '\\0') {\n\t  if(print)\n\t    stat_line_printf(\", \");\n\n\t  stat_line_printf(\"%s\/sec\", printspeed);\n\t  print = 1;\n\t}\n#endif\n\t\n#if defined STAT_LINE_SHOW_NOW ||\t\t\t\\\n  defined STAT_LINE_SHOW_READY\n\tchar timebuf&#91;128];\n#endif\n\t\n#ifdef STAT_LINE_SHOW_READY\n\tchar timebuf2&#91;128];\n#endif\n\t\n#ifdef STAT_LINE_SHOW_NOW\n\t\n\t\/\/ print now\n\t\n\tif(print)\n\t  stat_line_printf(\", \");\n\t\n\tstat_line_printf(\"now\");\n\tstrftime(timebuf, sizeof(timebuf), TIMEFORMAT2,\n\t\t localtime((time_t *)&amp;now));\n\tstat_line_printf(\" %s\", timebuf);\n\tprint = 1;\n#endif\n\t\n#ifdef STAT_LINE_SHOW_LEFT\n\t\n\t\/\/ print left\n\t\n\tif(printleft > 0) {\n\n\t  if(print)\n\t    stat_line_printf(\", \");\n\n\t  stat_line_printf(\"left\");\n\t  stat_line_dhms(printleft);\n\n\t  leftprinted = 1;\n\t  print = 1;\n\t}\n#endif\n\t\n#ifdef STAT_LINE_SHOW_READY\n\t\n\t\/\/unsigned long int end = (int)start + ((((double)now - start) \/ c) * clim);\n\n\tif(printend > 0 &amp;&amp; leftprinted) {\n\t  if(print)\n\t    stat_line_printf(\", \");\n\t  \n\t  stat_line_printf(\"ready at\");\n\t  strftime(timebuf, sizeof(timebuf), DATEFORMAT,\n\t\t   localtime((time_t *) &amp; end));\n\t  strftime(timebuf2, sizeof(timebuf2), DATEFORMAT,\n\t\t   localtime((time_t *) &amp; now));\n\t  if(strcmp(timebuf, timebuf2)) {\n\t    stat_line_printf(\" %s\", timebuf);\n\t  }\n\t  \n\t  \/\/ print end time\n\t  \n\t  strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t\t   localtime((time_t *) &amp; printend));\n\t  stat_line_printf(\" %s\", timebuf);\n\t  \n\t  print = 1;\n\t}\n#endif\n      }\n      stat_line_end();\n      stat_line_cursor_start();\n      \n      \/\/ do the work\n      \n      stat_line_cursor();\n\n      memset(buffer, 0, blocksize);\n            \n      if(input == INPUT_RESSU) \/\/ ressu prod\n\tressu_genbytes(blocksize, buffer);\n      \n      else if(input == INPUT_PSEUDORESSU) \/\/ pseudoressu\n\tpseudoressu_bytes(blocksize, buffer);\n      \n      else if(input == INPUT_RESSUTWIST) \/\/ ressu w twist\n\tressutwist_bytes(blocksize, buffer);\n\t\n      else if(input == INPUT_FASTRESSU) \/\/ ressu fast\n\tressu_genbytes_fast(blocksize, buffer);\n      \n      else if(input == INPUT_SINGLERESSU) \/\/ ressu single\n\tressu_genbytes_single(blocksize, buffer);\n      \n      else if(input == INPUT_STREAM) \/\/ ressu stream\n\tstream_bytes(blocksize, buffer);\n      \n      else if(input == INPUT_TEST) \/\/ test generator\n\ttest_bytes(blocksize, buffer);\n      \n#ifdef FORT\n      else if(input == INPUT_FORT) \/\/ ressu fort\n\tfort_random_data(blocksize, buffer);\n      \n      else if(input == INPUT_FORTXOR) \/\/ ressu fort\n\tfort_random_data_xor(blocksize, buffer);\n      \n#endif\n#ifdef USE_RDRAND\n      else if(input == INPUT_RDRAND) \/\/ intel rdrand\n\trdrand_bytes(blocksize, buffer);\n      \n#endif\n#ifdef USE_RDSEED\n      else if(input == INPUT_RDSEED) \/\/ intel rdseed\n\trdseed_bytes(blocksize, buffer);\n      \n#endif\n      else if(input == INPUT_URANDOM) \/\/ urandom\n\turandom_bytes(blocksize, buffer);\n      \n#ifdef USE_RANDOM\n      else if(input == INPUT_RANDOM) \/\/ random\n\trandom_bytes(blocksize, buffer);\n      \n#endif\n#ifdef USE_DUMMY\n      else if(input == INPUT_DUMMY) {\n\t\/\/ no generator\n      }\n#endif\n      else {\n\tfprintf(stdout,\"\\n%s: mode '%d'(%s) not available\\n\",\n\t\tprocname, input, input_str);\n\texit(2);\n      }\n#ifdef SAMPLE_HASH\n      HashUpdate(&amp;hash, buffer, blocksize); \/\/ calculate hash\n#endif\n#ifdef SAMPLE_WRITE\n      if(input != INPUT_DUMMY) {\n\tfwrite(buffer, 1, blocksize, fp1);\n\t\n#ifdef SAMPLE_SYNC\n\n#ifdef EXFAT_FIX\n\tif(c % mbinblocks == 0) { \/\/ fflush and sync (EXFAT)\n\t  fflush(fp1);\n\t  \/\/sync();\n\t  fsync(fileno(fp1));\n\t}\n#endif\n\n#endif\n      } \/\/ end of if(input != INPUT_DUMMY\n#endif\n    } \/\/ end of for(c = 0; c &lt; clim; c++\n#ifdef SAMPLE_HASH\n    HashFinal(digest, &amp;hash); \/\/ calculate hash\n#endif\n\n    fflush(fp1); \/\/ fflush and sync (EXFAT)\n    \/\/sync();\n    fsync(fileno(fp1));\n    \n    fclose(fp1);\n    \n  } else { \/\/ if((fp1=fopen\n    fprintf(stderr,\"%s:\", procname);\n    fprintf(stderr,\" sample(): cannot open file\");\n    fprintf(stderr,\", filename: %s\", filename);\n    fprintf(stderr,\"\\n\");\n    exit(2);\n  }\n  \n  \/\/ remove last status line\n\n  \/\/stat_line_cursor_remove();\n  \n  stat_line_begin();\n  \n  stat_line_printf(\"\\rwrote \");\n  stat_line_readable((unsigned long)c * blocksize);\n  \n  stat_line_printf(\", \");\n  if(now - start >= 1.0)\n    stat_line_readable((unsigned long)((double)c * blocksize \/ (now - start)) );\n  else\n    stat_line_readable((unsigned long)c * blocksize);\n  stat_line_printf(\"\/sec\");\n\n  end = time(NULL);\n  took = end - start;\n  stat_line_printf(\", took\");\n  stat_line_dhms(took);\n  \n  \/\/stat_line_printf(\", done!\");\n  stat_line_end();\n  stat_line_cursor_remove();\n  fprintf(stderr,\"\\n\");\n  fflush(stderr);\n\n#ifdef SAMPLE_HASH\n  unsigned char filename2&#91;138];\n  unsigned char hashstring&#91;2 * HashLen + 1];\n  \n  hashfinal2string(hashstring, digest);\n\n  sprintf(filename2,\"%s.sha256\", filename);\n  \n  fprintf(stderr,\"%s: sample(): hashing file\", procname);\n  fprintf(stderr,\", filename:%s\", filename);\n  fprintf(stderr,\", hashfilename:%s\", filename2);\n  fprintf(stderr,\", sha256:%s\\n\", hashstring);\n  \n  if((fp1 = fopen(filename2, \"a\")) != NULL) {\n    fprintf(fp1,\"%s\\n\",hashstring);\n    fclose(fp1);\n  }\n  sprintf(command,\"sha256sum %s\", filename);\n  fprintf(stderr,\"%s: sample(): checking sha256\", procname);\n  fprintf(stderr,\", filename:%s\", filename);\n  fprintf(stderr,\", command:'%s'\\n\", command);\n  system(command);\n#endif\n\n  signal(SIGINT, SIG_DFL);\n\n  memset(buffer, 0, blocksize); \/\/ forget buffer\n\n  free(buffer);\n  \n  if(dieharder) { \/\/ randomness analysis\n    \n    sprintf(command,\"dieharder -a -g 201 -f %s > %s.dieharder 2>&amp;1\",\n\t    filename, filename);\n    \/\/sprintf(command,\"dieharder -a -g 201 -f %s > %s.dieharder\", filename, filename);\n    fprintf(stderr,\"%s: sample(): running dieharder \\\"%s\\\"\\n\",\n\t    procname, command);\n    system(command);\n    sprintf(command,\"grep \\\"WEAK\\\\|FAILED\\\" %s.dieharder\",\n\t    filename);\n    fprintf(stderr,\"%s: sample(): grepping dieharder problems \\\"%s\\\"\\n\"\n\t    , procname, command);\n    system(command);\n\n    long long weak;\n    sprintf(command,\"grep WEAK %s.dieharder\", filename);\n    weak = command_countlines(command);\n    fprintf(stderr,\"%s: sample(): calculating WEAK lines\", procname);\n    fprintf(stderr, \", lines = %lld\", weak);\n    fprintf(stderr,\", \\\"%s\\\"\\n\", command);\n\n    long long failed;\n    sprintf(command,\"grep FAILED %s.dieharder\", filename);\n    failed = command_countlines(command);\n    fprintf(stderr,\"%s: sample(): calculating FAILED lines\", procname);\n    fprintf(stderr, \", lines = %lld\", failed);\n    fprintf(stderr,\", \\\"%s\\\"\\n\", command);\n\n    sprintf(command,\"grep rewound %s.dieharder | tail -n1\",\n\t    filename);\n    fprintf(stderr,\"%s: sample(): grepping last rewound count \\\"%s\\\"\\n\",\n\t    procname, command);\n    system(command);\n\n    FILE *fp2;\n    if((fp2 = fopen(\"newressudieharder.skk\", \"a\")) != NULL) { \/\/\n      fprintf(fp2,\"'input' = \\\"%s\\\"\", input_str);\n      if(filesize_str != NULL)\n\tfprintf(fp2,\", 'filesize' = \\\"%s\\\"\", filesize_str);\n      if(blocksize_str != NULL)\n\tfprintf(fp2,\", 'blocksize' = \\\"%s\\\"\", blocksize_str);\n      if(blocks_str != NULL)\n\tfprintf(fp2,\"'blocks' = \\\"%s\\\"\", blocks_str);\n      fprintf(fp2,\", 'filename' = \\\"%s\\\"\", filename);\n      fprintf(fp2,\", 'weak' = \\\"%lld\\\"\", weak);\n      fprintf(fp2,\", 'failed' = \\\"%lld\\\"\", failed);\n      fprintf(fp2,\"\\n\");\n      fclose(fp2);\n    }\n    \n    if(purge) {\n      fprintf(stderr,\"%s: sample(): removing file\", procname);\n      fprintf(stderr,\" %s\\n\", filename);\n      unlink(filename);\n    }\n    exit(0);\n  }\n}\n\nstatic unsigned long limit, word, uppercase = 0;\nstatic unsigned char *digits = \"0123456789\", character&#91;32];\nstatic unsigned char digitstemp&#91;256], *digitsext = NULL;\nstatic unsigned char linenobuf&#91;1024];\nstatic unsigned char *stream_default_key  = \"kalakala\";\nstatic unsigned char *key = NULL;\nstatic int print_statline = 0, columns = 0, flagdigits = 0;\n\nint help = 0;\n\n\/\/\n\/\/  utf8 functions\n\/\/\n\nstatic int utf8characters(unsigned char *buf)\n{\n  int characters;\n  unsigned char *p;\n  \n  p = buf;\n  characters = 0;\n  while(*p != '\\0') {\n    if(*p &lt; 0x80 || \/\/ ascii char\n       *p > 0xbf) \/\/ first utf8 byte\n      characters++;\n    p++;\n  }\n\n  if(flagdigits == 1) \/\/ semicolon separated (flags)\n    return(characters \/ 2);\n  else\n    return(characters);\n}\n\nint utf8strings(unsigned char *buf)\n{\n  int strings = 0;\n\n  unsigned char *p = buf;\n  while(*p != '\\0') {\n    if(*p == ';')\n      strings++;\n    p++;\n  }\n\n  return(strings);\n}\n\n#define aDEBUG47 2\n\nint utf8lengths(unsigned char *buf)\n{\n  int lengths, len, first = 1;\n  unsigned char *p;\n\n#ifdef DEBUG47 \n  fprintf(stdout,\"digits    %s\", buf);\n  fprintf(stdout,\"\\nlengths   \");\n#endif\n  \n  p = buf;\n  len = 0;\n  lengths = -1;\n  first = 1;\n\n  while(*p != '\\0') {\n    if(!first &amp;&amp;\n       (*p &lt; 0x80 || \/\/ ascii char\n\t*p > 0xbf)) { \/\/ first utf8 byte\n#ifdef DEBUG47\n      fprintf(stdout,\"%d\", len);\n#endif\n      if(lengths == -1)\n\tlengths = len;\n      else if(lengths != len)\n\tlengths = 0;\n      len = 0;\n    }\n    p++;\n    len++;\n    first = 0;\n  }\n\n#ifdef DEBUG47\n  fprintf(stdout,\"%d\", len);\n#endif\n  if(lengths == -1)\n    lengths = len;\n  else if(lengths != len)\n    lengths = 0;\n\n#ifdef DEBUG47\n  fprintf(stdout,\"\\nlengths   %d\\n\\n\", lengths);\n#endif\n  return(lengths);\n}\n\nint utf8stringlengths(unsigned char *buf)\n{\n  int lengths = -1, len;\n  unsigned char *p = buf;\n\n  \/\/ return(0);\n  \n  len = 0;\n  while(*p != '\\0') {\n    if(*p == ';') {\n      p++;\n      if(lengths == -1)\n\tlengths = len;\n      else if(lengths != len)\n\tlengths = 0;\n      len = 0;\n    }\n    p++;\n    len++;\n  }\n\n  if(lengths == -1)\n    lengths = 0;\n  else\n    lengths++; \/\/ count semicolon also\n\n  return(lengths);\n}\n\n#define aDEBUG42 2\n\nstatic void codetoutf8(unsigned char *buf2, unsigned long code)\n{\n  unsigned char *buf;\n\n  buf = buf2;\n  if(code &lt;= 0x7f) {\n    *buf++ = code;\n  } else if(code &lt;= 0x7ff) {            \/\/ 110xxxxx 10xxxxxx\n    *buf++ = (0xc0 | ((code >> 6) &amp; 0x1f));\n    *buf++ = (0x80 | (code &amp; 0x3f));\n  } else if(code &lt;= 0xffff) {           \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n    *buf++ = (0xe0 | ((code >> 12) &amp; 0x0f));\n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));\n    *buf++ = (0x80 | (code &amp; 0x3f));\n  } else if(code &lt;= 0x10ffff) {         \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *buf++ = (0xf0 | ((code >> 18) &amp; 0x07));\n    *buf++ = (0x80 | ((code >> 12) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code &amp; 0x3f)));      \n  } else if(code &lt;= 0x3ffffff) {        \/\/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++ = (0xf8 | ((code >> 24) &amp; 0x03));\n    *buf++ = (0x80 | ((code >> 18) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 12) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code &amp; 0x3f)));      \n  } else if(code &lt;= 0x7fffffff) {       \/\/ 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++ = (0xfc | ((code >> 30) &amp; 0x01));\n    *buf++ = (0x80 | ((code >> 24) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 18) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 12) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code &amp; 0x3f)));      \n  } else if(code &lt;= 0xfffffffff) {      \/\/ 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++ = (0xfe);\n    *buf++ = (0x80 | ((code >> 30) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 24) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 18) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 12) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code &amp; 0x3f)));      \n  } else if(code &lt;= 0x3ffffffffff) {    \/\/ 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++ = (0xff);\n    *buf++ = (0x80 | ((code >> 36) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 30) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 24) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 18) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 12) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code >> 6) &amp; 0x3f));      \n    *buf++ = (0x80 | ((code &amp; 0x3f)));      \n  }\n  *buf = '\\0';\n\n#ifdef DEBUG42\n  int c, print;\n\n  fprintf(stdout,\"codepoint: %lx\", code);\n\n  fprintf(stdout,\", bin:\");\n\n  print = 0;\n  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {\n    int bit = (code >> c) &amp; 1;\n    if(bit != 0)\n      print = 1;\n    if(print) {\n      fprintf(stdout,\"%d\", bit);\n      if(c > 0 &amp;&amp; c % 8 == 0)\n\tfprintf(stdout,\"|\");\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  print = 0;\n  fprintf(stdout,\"%lo\", code);\n\n  fprintf(stdout,\", utf8: \");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    fprintf(stdout,\"%02x\", buf2&#91;c]);\n  }\n\n  fprintf(stdout,\", bin: \");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    if(c > 0)\n      fprintf(stdout,\"|\");\n    for(int d = 7; d >= 0; d--) {\n      fprintf(stdout,\"%d\", buf2&#91;c] >> d &amp; 1);\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    fprintf(stdout,\" %3o\", buf2&#91;c]);\n  }\n  \n  fprintf(stdout,\", character: %s\", buf2);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#ifdef NOTUSED\n\n#define aDEBUG43 2\n\nstatic void utf8tocode(unsigned long *code, unsigned char *buf2)\n{\n  unsigned char *buf;\n  \n  *code = 0;\n  buf = buf2;\n  \n  if(*buf &lt;= 0x7f) {                  \/\/ 0xxxxxxx\n    *code = *buf;\n  } else if(*buf &lt; 0xc0) {            \/\/ 110xxxxx 10xxxxxx\n    *code = 0;\n  } else if(*buf &lt; 0xe0) {            \/\/ 110xxxxx 10xxxxxx\n    *code = *buf++ &amp; 0x1f;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf &lt; 0xf0) {            \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n    *code = *buf++ &amp; 0x0f;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf&lt;0xf8) {            \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code = *buf++ &amp; 0x07;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf &lt; 0xfc) {            \/\/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code = *buf++ &amp; 0x03;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf &lt; 0xfe) {            \/\/ 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code = *buf++ &amp; 0x01;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf &lt; 0xff) {            \/\/ 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    buf++;\n    *code = *buf++ &amp; 0x3f;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  } else if(*buf == 0xff) {            \/\/ 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    buf++;\n    *code = *buf++ &amp; 0x3f;\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n    *code = (*code &lt;&lt; 6) + (*buf++ &amp; 0x3f);\n  }\n#ifdef DEBUG43\n  int c;\n\n  fprintf(stdout, \"character: %s\", buf2);\n\n  fprintf(stdout, \", utf8: \");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    fprintf(stdout,\"%02x\", buf2&#91;c]);\n  }\n\n  fprintf(stdout, \", bin: \");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    if(c > 0)\n      fprintf(stdout, \"|\");\n    for(int d = 7; d >= 0; d--)\n      fprintf(stdout, \"%d\", buf2&#91;c] >> d &amp; 1);\n  }\n\n  fprintf(stdout, \", oct:\");\n  for(c = 0; c &lt; 8; c++) {\n    if(buf2&#91;c] == '\\0')\n      break;\n    fprintf(stdout, \" %3o\", buf2&#91;c]);\n  }\n  \n  fprintf(stdout, \", codepoint: %lx\", *code);\n  fprintf(stdout, \", bin:\");\n  int print = 0;\n  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {\n    int bit = (*code >> c) &amp; 1;\n    if(bit != 0)\n      print = 1;\n    if(print) {\n      fprintf(stdout, \"%d\", bit);\n      if(c > 0 &amp;&amp; c % 8 == 0)\n\tfprintf(stdout, \"|\");\n    }\n  }\n\n  fprintf(stdout, \", oct:\");\n  fprintf(stdout, \"%lo\", *code);\n  \n  fprintf(stdout, \"\\n\");\n#endif\n}\n\n#endif \n\nint characterlengths = 0; \/\/ 0 multiple lengths, x lengths are same\n\n#define aDEBUG55 2\n\nstatic void utf8getcharactersemi(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  if(characterlengths != 0)\n    p += characterlengths * n;\n  else {\n    if(flagdigits) { \/\/ semicolon separated (flags)\n      while(*p != '\\0') {\n\tif(d == n)\n\t  break;\n\tif(*p == ';') {\n\t  d++;\n\t}\n\tp++;\n      }\n    } else { \/\/ else if(flagdigits)\n      while(*p != '\\0') {\n\tif(*p &lt; 0x80 || \/\/ ascii char\n\t   *p > 0xbf) { \/\/ first utf8 char\n\t  if(d == n)\n\t    break;\n\t  d++;\n\t}\n\tp++;\n      }\n    }\n  }\n  \/\/fprintf(stdout,\"%d***%s\\n\",d,p);\n\n  \/\/ copy first byte and rest\n  \/\/ of character\n\n  if(flagdigits) { \/\/ semicolon separated (flags)\n    while(*p != '\\0') {\n      if(*p == ';')\n\tbreak;\n      *q++ = *p++; \/\/ copy first byte\n    }\n  } else {\n    if(*p != '\\0') {\n      *q++ = *p; \/\/ copy first byte\n      if(*p > 0xbf) { \/\/ if first is utf8 char\n\tp++;\n\tfor(;;) {\n\t  if(*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\t}\n      }\n    }\n  }\n\n  *q = '\\0';\n  \/\/fprintf(stdout,\"character: `%s`\\n\", buf);\n\n#ifdef DEBUG56\n  fprintf(stdout,\"%s: utf8getcharacter:\", procname);\n  fprintf(stdout,\" string: %s\", string);\n  fprintf(stdout,\", n: %d\", n);\n  fprintf(stdout,\", character: %s\", buf);\n  fprintf(stdout,\", characterlengths: %d\", characterlengths);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nstatic void utf8getcharacter(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  if(characterlengths != 0)\n    p += characterlengths * n;\n  else {\n    while(*p != '\\0') {\n      if(*p &lt; 0x80 || \/\/ ascii char\n\t *p > 0xbf) { \/\/ first utf8 char\n\tif(d == n)\n\t  break;\n\td++;\n      }\n      p++;\n    }\n  }\n  \/\/fprintf(stdout,\"%d***%s\\n\",d,p);\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\n  *q = '\\0';\n\n#ifdef DEBUG56\n  fprintf(stdout,\"%s: utf8getcharacter:\", procname);\n  fprintf(stdout,\" string: %s\", string);\n  fprintf(stdout,\", n: %d\", n);\n  fprintf(stdout,\", character: %s\", buf);\n  fprintf(stdout,\", characterlengths: %d\", characterlengths);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#define aDEBUG56 2\n\nstatic void utf8getcharacter1(int size, unsigned char *buf, int n, unsigned char *string)\n{\n  unsigned char *p, *q;\n  \n  p = string;\n  q = buf;\n\n  \/\/ find first byte of character\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 DEBUG56\n  fprintf(stdout,\"%s: utf8getcharacter:\", procname);\n  fprintf(stdout,\" string: %s\", string);\n  fprintf(stdout,\", n: %d\", n);\n  fprintf(stdout,\", character: %s\", buf);\n  fprintf(stdout,\", characterlengths: %d\", characterlengths);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#define aDEBUG45 2\n\nint digitscount = 10;\n\n\/\/ display word in \"digits\" base (random data)\n\nstatic void out_word(int size, unsigned char *buf, unsigned char *digits, unsigned long word2) \/\/ 8.5.2021 JariK\n{\n  int c, d, len;\n  unsigned long word;\n  unsigned char string&#91;1024], character&#91;128];\n\n  \/\/digitscount = utf8characters(digits);\n  word = word2;\n  len = 0;\n  string&#91;0] = '\\0';\n\n  if(word == 0 || digitscount &lt; 2) {\n    \/\/ zero\n    utf8getcharactersemi(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      utf8getcharactersemi(sizeof(character), character, word%digitscount, digits);\n      if(len + strlen(character) &lt; sizeof(string)) {\n\tstrcat(string, character);\n\tlen += strlen(character);\n      }\n      word \/= digitscount;\n    }\n  }\n\n#ifdef DEBUG45\n  fprintf(stdout,\"]\\n%s: out_word a:\", procname);\n  fprintf(stdout,\" orig string: %s\", string);\n#endif\n  \n  \/\/ reverse string\n\n  if(flagdigits) \/\/ semicolon separated (flags)\n    strcpy(buf, string);\n  else {\n    *buf = '\\0';\n    len = 0;\n    d = utf8characters(string);\n    for(c = d - 1; c >= 0; c--) {\n      utf8getcharacter(sizeof(character), character, c, string);\n      if(len + strlen(character) &lt; size) {\n\tstrcat(buf, character);\n\tlen += strlen(character);\n      }\n    }\n  }\n\n#ifdef DEBUG45\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\/\/ display word in decimal (10-base) (line number)\n\nstatic void out_word_10(int size, unsigned char *buf, unsigned long word2) \/\/ 8.5.2021 JariK\n{\n  int c, d, len;\n  unsigned long word;\n  unsigned char string&#91;128], character&#91;32];\n  unsigned char *digits10 = \"0123456789\";\n  int digitscount = 10;\n  \n  \/\/digitscount = utf8characters(digits);\n  word = word2;\n  len = 0;\n  string&#91;0] = '\\0';\n\n  if(word == 0 || digitscount &lt; 2) {\n    \/\/ zero\n    utf8getcharacter1(sizeof(character), character, 0, digits10);\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      utf8getcharacter1(sizeof(character), character, word % digitscount, digits10);\n      if(len + strlen(character) &lt; sizeof(string)) {\n\tstrcat(string, character);\n\tlen += strlen(character);\n      }\n      word \/= digitscount;\n    }\n  }\n\n  \/\/ reverse string\n  \n  *buf = '\\0';\n  len = 0;\n  d = utf8characters(string);\n  for(c = d - 1;c >= 0; c--) {\n    utf8getcharacter1(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 b:\", 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\nstatic void 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 = utf8characters(buf);\n  if(flagdigits) \/\/ semicolon separated (flags)\n    f = utf8strings(digits);\n  else \/\/ not\n    f = utf8characters(digits);\n    \n  for(c = 0; c &lt; d; c++) {\n    utf8getcharacter(sizeof(character2), character2, c, buf);\n    ok = 0;\n    for(e = 0; e &lt; f; e++) {\n      utf8getcharactersemi(sizeof(character), character, e, digits); \/\/ semi added\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    }\n  }\n\n#ifdef DEBUG45\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}\n\n\/\/\n\/\/ lotto functions\n\/\/\n\nstatic void 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\nstatic int 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\nstatic void line_get_string(int len, unsigned char *buf,\n\t\t\t    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\n#define DEBUG59 2 \/\/ default is on for now\n\n#ifdef DEBUG59\nstatic int utf8 = 0;\n#endif\n\n#ifdef DEBUG51\nstatic int limitsize = 0;\n#endif\n\n#define aDEBUG51 2\n\nstatic void 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 = newressu_gen_limit(limit); \/\/ include zeroes\n    } else if(limit >= 1) {\n      while((word = newressu_gen_limit(limit)) == 0); \/\/ skip zeroes\n    }\n#ifdef DEBUG51\n    if(type == 2)\n      fprintf(stdout, \"(%0*lx)\", limitsize, word);\n    else if(type == 8)\n      fprintf(stdout, \"(%0*lo)\", limitsize, word);\n    else if(type == 10)\n      fprintf(stdout, \"(%0*lu)\", limitsize, word);\n    else if(type == 16)\n      fprintf(stdout, \"(%0*lx)\", limitsize, word);\n    else {\n      fprintf(stdout, \"(%02lu)\", word);\n    }\n#endif\n\t  \n    out_word(sizeof(temp1024), temp1024, digits, word);\n\t  \n    \/\/ fill leading zeroes\n    \n    buf&#91;0] = '\\0';\n    utf8getcharactersemi(sizeof(character), character, 0, digits);\n    for(d = size - utf8characters(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\t  \n    buf&#91;0] = '\\0';\n\t  \n#ifdef DEBUG51\n    fprintf(stdout, \"(\");\n#endif\n    \/\/ fill whole word digit by digit\n    for(d = 0; d &lt; size; d++) {\n      if(digits&#91;0] == '0' &amp;&amp; !zero)\n\te = newressu_gen_limit(digitscount - 1) + 1;\n      else\n\te = newressu_gen_limit(digitscount);\n      utf8getcharacter(sizeof(temp1024), temp1024, e, digits);\n#ifdef DEBUG51\n      fprintf(stdout,\"%s\", temp1024);\n      if(charspaces == 1)\n\tfputc(' ', stdout);\n#endif\n      strcat(buf, temp1024);\n    }\n#ifdef DEBUG51\n    fprintf(stdout, \")\");\n#endif\n  }\n}\n\n\/\/\n\/\/ stdout printing routines\n\/\/\n\nstatic int line_number_length()\n{\n  int c;\n  out_word_10(sizeof(linenobuf), linenobuf, lines-1);\n  c = strlen(linenobuf);\n  if(c &lt; 5)\n    c = 5;\n  return(c);\n}\n\nstatic void print_line_number()\n{\n  unsigned char linenobuf&#91;32];\n  \n  if(cwords == 0 &amp;&amp; slineno) {\n    if(newressu_output) {\n      fprintf(stdout,\"\\n\");\n      newressu_output = 0;\n    }\n    sprintf(linenobuf,\"%0*llu\", plinesdigits, plines);\n    fprintf(stdout,\"%s\", linenobuf);\n    fprintf(stdout,\" \");\n  }\n}\n\nstatic void print_word(unsigned char *buf)\n{\n  int e;\n  \n  if(size != 0) {\n    if(charspaces == 0) {\n      fprintf(stdout, \"%s\", buf);\n    } else {\n      for(e = 0; e &lt; size; e++) {\n\tunsigned char temp1024&#91;1024];\n\tutf8getcharacter(sizeof(temp1024), temp1024, e, buf);\n\tfprintf(stdout, \"%s\", temp1024);\n\tfputc(' ', stdout);\n      }\n    }\n  } else {\n    fprintf(stdout, \"%s\", buf);\n    if(charspaces == 1) {\n      fputc(' ', stdout);\n    }\n  }\n}\n\n#ifdef SHA256\n\nstatic void newressu_file_digest(char *filename,unsigned char *hash)\n{\n  int c;\n  unsigned char buffer&#91;1024];\n  FILE *fp1;\n  HashCtx ctx;\n  \n  HashInit(&amp;ctx);\n  if((fp1 = fopen(filename, \"rb\")) != NULL) {\n    while((c = fread(buffer, 1, sizeof(buffer), fp1)) > 0)\n      HashUpdate(&amp;ctx, buffer, c);\n    fclose(fp1);\n  }\n  HashFinal(hash, &amp;ctx);  \n}\n\n#endif\n\n#define aDEBUG55 2\n#define aDEBUG57 2\n\nvoid digits_add_string(unsigned char **digits, char *str)\n{\n  int digitssize;\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\", *digits);\n  fprintf(stdout,\"\\nadddigits %s\", str);\n#endif\n  digitssize = 0;\n  if(*digits != NULL)\n    digitssize += strlen(*digits);\n  digitssize += strlen(str);\n\n#ifdef DEBUG57\n  fprintf(stdout,\"digitssize:%d\\n\", digitssize);\n  fflush(stdout);\n#endif\n\n  unsigned char *prevdigits = *digits;\n  *digits = realloc(*digits, digitssize + 1);\n  if(prevdigits == NULL)\n    **digits = '\\0';\n\n  strcat(*digits, str);\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\", *digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nvoid digits_add_limits(unsigned char **digits, int start, int end)\n{\n  int c, digitssize;\n  unsigned char buffer&#91;32];\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\", *digits);\n  fprintf(stdout,\"\\nadddigits start:%d, end:%d\", start, end);\n#endif\n  digitssize = 0;\n  if(*digits != NULL)\n    digitssize += strlen(*digits);\n  \n  for(c = start; c &lt;= end; c++) {\n    codetoutf8(buffer, c);\n    digitssize += strlen(buffer);\n  }\n\n#ifdef DEBUG57\n  fprintf(stdout,\"digitssize:%d\\n\", digitssize);\n  fflush(stdout);\n#endif\n  \n  unsigned char *prevdigits = *digits;\n  *digits = realloc(*digits, digitssize + 1);\n  if(prevdigits == NULL)\n    **digits = '\\0';\n\n  for(c = start; c &lt;= end; c++) {\n    codetoutf8(buffer, c);\n    strcat(*digits, buffer);\n  }\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\", *digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nvoid strtolower(unsigned char *buf)\n{\n  while(*buf != '\\0') {\n    *buf = tolower(*buf);\n    buf++;\n  }\n}\n\nvoid strtoupper(unsigned char *buf)\n{\n  while(*buf != '\\0') {\n    *buf = toupper(*buf);\n    buf++;\n  }\n}\n\ndouble getseconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return((double)tv.tv_sec + (double)tv.tv_usec \/ 1000000);\n}\n\nint newressu_getname(int length, unsigned char *name, unsigned char **p2)\n{\n  int len, ok = 0;\n  unsigned char *n, *p;\n\n  p = *p2;\n  n = name;\n  len = 0;\n  \n  while(ispunct(*p) || isblank(*p)) {\n    p++;\n  }\n\n  while(*p != '\\0' &amp;&amp; !ispunct(*p) &amp;&amp; !isblank(*p)) {\n    if(len &lt; length) {\n      *n++ = *p;\n      ok = 1;\n    }\n    p++;\n    len++;\n  }\n  *n = '\\0';\n  \n  *p2 = p;\n\n  return(ok);\n}\n\nvoid newressu_base(int base2)\n{\n  base = base2;\n  \n  digits = malloc(base + 1);\n  strncpy(digits, basedigits, base);\n  if(uppercase == 1 &amp;&amp; base &lt;= 36) { \/\/ if lowercase only (&#91;0-9] + &#91;a-z], 10 + 26\n    for(int c = 0; c &lt; base; c++) { \/\/ to uppercase\n      if(digits&#91;c] >= 'a' &amp;&amp; digits&#91;c] &lt;= 'z')\n\tdigits&#91;c] = digits&#91;c] - 'a' + 'A';\n      else if(digits&#91;c] >= 'A' &amp;&amp; digits&#91;c] &lt;= 'Z')\n\tdigits&#91;c] = digits&#91;c] - 'A' + 'a';\n    }\n  }\n  if(digitsext != NULL)\n    free(digitsext);\n  digitsext = digits;\n  \n  digits&#91;base] = '\\0';\n}\n\n#include &lt;sys\/ioctl.h> \/\/ for TIOCGWINSZ\n\n#define aDEBUG50 2\n#define aDEBUG71 2\n\nvoid call_main(char *);\n\n#define aCALL_MAIN 2\n\n#ifdef CALL_MAIN\n\n#define DEBUG99 2\n\nint main2(int argc, char *argv&#91;]);\n\nvoid call_main(char *cmd)\n{\n  int size, round, count, chars;\n  unsigned char *p, *q, *argmem,*params;\n  char **argv;\n\n  size = 0;\n\n  for(round = 0; round &lt; 2; round++) {\n    count = 0;\n    p = cmd;\n    while(*p != '\\0') {\n      while(*p == ' ' || *p == '\\t')\n\tp++;\n      q = p;\n      chars = 0;\n      while(*p != ' ' &amp;&amp;  *p != '\\t' &amp;&amp; *p != '\\0') {\n\tp++;\n\tchars++;\n      }\n      if(round == 0) \/\/ calculate size &amp; alloc\n\tsize += chars + 1 + sizeof(char *);\n      else { \/\/ move parameters to arg area\n\tstrncpy(params, q, chars);\n\t*(argv+count) = params;\n\tparams += (chars+1);\n      }\n      count++;\n    }\n    if(round == 0) { \/\/ allocate\n      size += sizeof(char *); \/\/ ending NULL\n      argmem = malloc(size);\n      argv = (char **)argmem;\n      params = argmem + sizeof(char *) * (count+1);\n    }\n  }\n\n  *(argv+count) = NULL; \/\/ ending NULL\n\n#ifdef DEBUG99\n  \n  fprintf(stdout, \"size:%d,\", size);\n  fprintf(stdout, \" argmem:\");\n  for(int c = 0; c &lt; size; c++) {\n    if(c > 0 &amp;&amp; c % 8 == 0)\n      fprintf(stdout, \"|\");\n    if(*(argmem+c) == '\\\\')\n      fprintf(stdout, \"\\\\\\\\\");\n    if(isprint(*(argmem + c)))\n      fprintf(stdout, \"%c\", *(argmem + c));\n    else\n      fprintf(stdout, \"\\\\%02x\", *(argmem + c));\n  }\n  fprintf(stdout, \"\\n\");\n\n#endif \/\/ #ifdef DEBUG99\n\n  main2(count, argv);\n}\n\nint main(int argc, char *argv&#91;])\n{\n  int first;\n  char buffer&#91;1024];\n\n  first = 1;\n  buffer&#91;0] = '\\0';\n  for(int c = 0; c &lt; argc; c++) {\n    if(!first)\n      strcat(buffer, \" \");\n    strcat(buffer, argv&#91;c]);\n    first = 0;\n  }\n#ifdef DEBUG99\n  fprintf(stdout,\"main: cmd \\\"%s\\\"\\n\",buffer);\n#endif\n  \n  call_main(buffer);\n}\n\n#endif \/\/ #ifdef CALL_MAIN\n\n#ifdef CALL_MAIN\n\nint main2(int argc, char *argv&#91;])\n{\n#ifdef DEBUG99\n  fprintf(stdout, \"main2args:\");  \n  for(int c = 0; c &lt; argc; c++) {\n    fprintf(stdout, \" %d:\\\"%s\\\"\", c, argv&#91;c]);\n  }\n  fprintf(stdout, \"\\n\");\n#endif \/\/ #ifdef DEBUG99\n\n#else \/\/ #ifdef CALL_MAIN\n\nstatic unsigned char programfiledigest&#91;HashLen];\n\nint main(int argc, char *argv&#91;])\n{\n#endif \/\/ #ifdef CALL_MAIN\n  \n  int c, d, status = 0;\n\n#ifdef DEBUG2H\n\n  for(int c = 0; c &lt; RESSUT_BYTES; c++)\n    count&#91;c] = 0;\n\n#endif\n\n  procname = argv&#91;0];\n\n#define aDEBUG67A 2\n\n#ifdef DEBUG67A\n  unsigned long long big = 0xffffffffffffffff;\n  fprintf(stdout,\"0x%llx\\n\", big);\n  fprintf(stdout,\"0o%llo\\n\", big);\n  fprintf(stdout,\"0d%llu\\n\", big);\n  fprintf(stdout,\"0x%llx\\n\", big);\n  for(int base = 2; base &lt;= 64; base++) {\n    fprintf(stdout,\"base:%d, \", base);\n    fprintfbase(stdout, big, base);\n    fprintf(stdout,\"\\n\");\n  }\n  fprintf(stdout,\"number\");\n  for(int base = 2; base &lt;= 64; base++) {\n    fprintf(stdout,\" %d\",base);\n  }\n  fprintf(stdout,\"\\n\");\n  for(unsigned long long ll = 0; ll &lt; 1048576; ll++) {\n  \/\/for(unsigned long long ll = 4096; ll > 0; ll+=4096) {\n  \/\/for(unsigned long long ll = 1; ll != 0; ll *= 2) {\n    fprintf(stdout,\"%llu:\", ll);\n    for(int base = 2; base &lt;= 64; base++) {\n      fprintf(stdout,\" \");\n      fprintfbase(stdout, ll, base);\n    }\n    fprintf(stdout,\"\\n\");\n  }\n  fflush(stdout);\n#endif\n\n#define aDEBUG67B 2\n  \n#ifdef DEBUG67B\n\n  unsigned char buffer4096&#91;4096];\n  unsigned char buffer&#91;128];\n  \n  stream_open(0, stream_default_key);\n\n  \/\/ fprintf(stderr,\"read\\n\");\n  stream_bytes(sizeof(buffer4096), buffer4096);\n  \/\/buffer4096&#91;2048] = 1;\n\n  \/\/ fprintf(stderr,\"second read\\n\");\n  \n  for(int c = 1; c &lt; sizeof(buffer); c++) {\n    \/\/ fprintf(stdout,\"%d\", c);\n    stream_open(0, stream_default_key);\n    for(int d = 0; d &lt; sizeof(buffer4096) - c + 1; d += c) {\n      \/\/ fprintf(stdout,\" %d\", d);\n      stream_bytes(c, buffer);\n      if(memcmp(buffer, buffer4096 + d, c)) {\n\tfprintf(stderr,\"%s: compare mismatch (stream), c=%d, d=%d\\n\", procname, c, d);\n\t\/\/ exit(1);\n      }\n    }\n    \/\/ fprintf(stdout,\"\\n\");\n  }\n#endif\n\n#define aDEBUG69\n  \n#ifdef DEBUG69\n  stream_open(0, \"\u2680\u2681\u2682\u2683\u2684\u2685\"); \/\/ utf8  \n  stream_open(0, \"Hasta la vista, baby (Arnold Schwarzenegger, T2)\"); \/\/ pass phrase\n  stream_open(0, \"abcdefghijklmnopqrstuvwxyz\" \/\/ long password (key)\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"\n\t      \"abcdefghijklmnopqrstuvwxyz\"); \n  stream_open(5, \"\\x00\\x01\\x02\\x03\\x04\"); \/\/ binary string with length\n#endif\n  \n#define aDEBUG73\n\n#ifdef DEBUG73\n\n  unsigned char buf&#91;128];\n  command_readline(\"date +%Y%m%d%H%M\", sizeof(buf), buf);\n  fprintf(stdout,\"readline date '%s'\\n\",buf);\n\n#endif\n  \n#define aDEBUG74\n\n#ifdef DEBUG74\n\n  char *ds&#91;] = { \"A\", \"B\", \"T\", \"J\", \"X\", \"KH\", \"D\", \"R\", \"S\", \"SH\",\n\t\t \"DH\", \"C\", \"G\", \"F\", \"Q\", \"K\", \"L\", \"M\", \"N\", \"W\",\n\t\t \"H\", \"Y\", \"E\", \"O\" }; \/\/ --som\n  for(c= 0; c &lt; sizeof(ds) \/ sizeof(ds&#91;0]); c++)\n    fprintf(stdout,\" `%s`\",ds&#91;c]);\n  fprintf(stdout,\"\\n\");\n\n#endif\n\n  unsigned char *flagchars&#91;] =\n    { \"\ud83c\udde6\", \"\ud83c\udde7\", \"\ud83c\udde8\", \"\ud83c\udde9\", \"\ud83c\uddea\", \"\ud83c\uddeb\", \"\ud83c\uddec\", \"\ud83c\udded\", \"\ud83c\uddee\", \"\ud83c\uddef\",\n      \"\ud83c\uddf0\", \"\ud83c\uddf1\", \"\ud83c\uddf2\", \"\ud83c\uddf3\", \"\ud83c\uddf4\", \"\ud83c\uddf5\", \"\ud83c\uddf6\", \"\ud83c\uddf7\", \"\ud83c\uddf8\", \"\ud83c\uddf9\",\n      \"\ud83c\uddfa\", \"\ud83c\uddfb\", \"\ud83c\uddfc\", \"\ud83c\uddfd\", \"\ud83c\uddfe\", \"\ud83c\uddff\" };\n  \n#define DEBUG70\n\n#ifdef DEBUG70\n\n  for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n    unsigned char buffer20&#91;20];\n    unsigned char buffer128&#91;128];\n    sprintf(buffer128,\" %s\", idsflags&#91;c].flags);\n    unsigned char *p = buffer128;\n    if(idsflags&#91;c].id&#91;0] !=  '\\0')\n      continue;\n    buffer20&#91;0] = '\\0';\n    for(d = 0; *p != '\\0'; d++) {\n      if(isalpha(*p) == 0 &amp;&amp;\n\t islower(*(p + 1)) != 0 &amp;&amp;\n\t islower(*(p + 2)) != 0 &amp;&amp;\n\t isalpha(*(p + 3)) == 0) {\n\tstrcat(buffer20, flagchars&#91;toupper(*(p + 1)) - 'A']);\n\tstrcat(buffer20, flagchars&#91;toupper(*(p + 2)) - 'A']);\n      }\n      p++;\n    }\n    fprintf(stdout,\"  { \\\"%s\\\"\", buffer20);\n    fprintf(stdout,\", \\\"%s: %s\\\" },\\n\", buffer20, idsflags&#91;c].flags);\n    fflush(stdout);\n  }\n  \n#endif\n\n#define aDEBUG68A \/\/ default is off\n\n#ifdef DEBUG68A\n\n  unsigned char *hindi = malloc(8192);\n  digits_add_limits(&amp;hindi,0x900,0x97f);   \/\/ Hindi (0900-097f)\n  unsigned char *h;\n  int first;\n\n  \/\/fprintf(stdout,\"hindi1: %s\\n\", hindi);\n  h = hindi;\n  first = 1;\n  while(*h != '\\0') {\n    if(!first)\n      fprintf(stdout, \" \");\n    fputc(*h, stdout); \/\/ print first char\n    if(*h > 0xbf) { \/\/ first char utf8\n      h++;\n      for(;;) { \/\/ print rest of the utf8 chars\n\tif(*h > 0xbf || \/\/ new utf8 character\n\t   *h &lt; 0x80 || \/\/ ascii character\n\t   *h == '\\0') \/\/ end of string\n\t  break;\n\tfputc(*h, stdout);\n\th++;\n      }\n    }\n    first = 0;\n  }\n  fprintf(stdout,\"\\n\");\n  free(hindi);\n  \n#endif\n\n#define aDEBUG68B\n#ifdef DEBUG68B\n  fprintf(stdout,\"hebrew: \");\n  unsigned char *hebrew = malloc(8192);\n  digits_add_limits(&amp;hebrew, 0x590, 0x5ff);   \/\/  (0590-05ff)\n  \/\/ \u0590\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059a\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05c4\u05c5\u05c6\u05c7\u05c8\u05c9\u05ca\u05cb\u05cc\u05cd\u05ce\u05cf\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05eb\u05ec\u05ed\u05ee\u05ef\u05f0\u05f1\u05f2\u05f3\u05f4\u05f5\u05f6\u05f7\u05f8\u05f9\u05fa\u05fb\u05fc\u05fd\u05fe\u05ff\n  fprintf(stdout,\"%s\\n\", hebrew);\n#endif\n\n#define aDEBUG68C\n#ifdef DEBUG68C\n  fprintf(stdout,\"phoenician: \");\n  unsigned char *phoenician = malloc(8192);\n  digits_add_limits(&amp;phoenician, 0x10900, 0x1091f);   \/\/  (10900-1091f)\n  \/\/phoenician: \ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd03\ud802\udd04\ud802\udd05\ud802\udd06\ud802\udd07\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd0b\ud802\udd0c\ud802\udd0d\ud802\udd0e\ud802\udd0f\ud802\udd10\ud802\udd11\ud802\udd12\ud802\udd13\ud802\udd14\ud802\udd15\ud802\udd16\ud802\udd17\ud802\udd18\ud802\udd19\ud802\udd1a\ud802\udd1b\ud802\udd1c\ud802\udd1d\ud802\udd1e\ud802\udd1f\n  fprintf(stdout,\"%s\\n\", phoenician);\n#endif\n  \n  limit = 0;\n  newressu_file_digest(\"\/proc\/self\/exe\", programfiledigest);\n\n  newressu_clear();\n\n  clockbytes = 0;\n  for(d = 0; d &lt; 1024; d++)\n    periods&#91;d] = 0;\n\n#ifdef USE_TIMER\n  int timer = 0;\n  double timerstart;\n#endif  \n\n#define aDEBUG72 \/\/ default is on\n\t\t     \n#ifdef DEBUG19\t\n  int flagint = 1;\n#endif\n\n  idsall = 1;\n  newressu_toggleflag(\"ALL\");\n  int flagsinit = 0;\n\t\t     \n  \/\/\n  \/\/ look thru command line parameters\n  \/\/ for flags option\n  \/\/\n\n  int flagflags = 0;\n  for(c = 1; c &lt; argc; c++) {\n    if(!strcmp(\"--flags\", argv&#91;c])) { \/\/ not ready\n      flagflags = 1;\n    }\n  }\n\n  \/\/\n  \/\/ look thru command line parameters\n  \/\/\n\n  for(c = 1; c &lt; argc; c++) {\n\n    int ok = 1;\n\n    if(!strncmp(\"-\", argv&#91;c], 1)) {\n\n      if(!strcmp(\"--help\", argv&#91;c]) ||\n\t !strcmp(\"-?\", argv&#91;c])) {\n\thelp = 1;\n\t\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(\"--digits\", argv&#91;c])) {\n\tflagprintdigits = !flagprintdigits;\n\n      } else if(!strcmp(\"--columns\", argv&#91;c])) {\n\tcolumns = !columns; \/\/ print column numbers\n\t\n      } else if(!strncmp(\"--space\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  sspace = atoi(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc &amp;&amp; isdigit(*(argv&#91;c + 1]))) {\n\t  sspace = atoi(argv&#91;c + 1]);\n\t  c++;\n\t} else {\n\t  sspace = !sspace;\n\t}\n\n      } else if(!strncmp(\"--newline\", argv&#91;c], 9)) {\n\tif(*(argv&#91;c] + 9) != '\\0' &amp;&amp; atoi(argv&#91;c] + 9) > 0) {\n\t  snewline = atoi(argv&#91;c] + 9);\n\t} else if(c + 1 &lt; argc &amp;&amp; atoi(argv&#91;c + 1]) > 0) {\n\t  snewline = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\n      } else if(!strcmp(\"--sample\", argv&#91;c])) {\n\tsample = !sample;\n\t\n      } else if(!strcmp(\"--dieharder\", argv&#91;c])) {\n\tdieharder = !dieharder;\n\t\n      } else if(!strcmp(\"--purge\", argv&#91;c])) {\n\tpurge = !purge;\n\tpurge_set = 1;\n\t\n      } else if(!strcmp(\"--save\", argv&#91;c])) {\n\tpurge = 1;\n\tpurge_set = 1;\n\t\n#ifdef DEBUG59\n      } else if(!strcmp(\"--utf8\", argv&#91;c])) {\n\tutf8 = !utf8;\n\t\n#endif\n      } else if(!strncmp(\"--filesize\", argv&#91;c], 10)) {\n\tif(*(argv&#91;c] + 10) != '\\0') {\n\t  filesize_str = argv&#91;c] + 10;\n\t  filesize = getlonglong(filesize_str);\n\t} else if(c + 1 &lt; argc) {\n\t  filesize_str = argv&#91;c + 1];\n\t  filesize = getlonglong(filesize_str);\n\t  c++;\n\t}\n\tfilesize_set = 1;\n\n      } else if(!strncmp(\"--blocksize\", argv&#91;c], 11)) {\n\tif(*(argv&#91;c] + 11) != '\\0') {\n\t  blocksize_str = argv&#91;c] + 10;\n\t  blocksize = getlonglong(blocksize_str);\n\t} else if(c + 1 &lt; argc) {\n\t  blocksize_str = argv&#91;c + 1];\n\t  blocksize = getlonglong(blocksize_str);\n\t  c++;\n\t}\n\tblocksize_set = 1;\n\t\n      } else if(!strncmp(\"--blocks\", argv&#91;c], 8)) {\n\tif(*(argv&#91;c] + 8) != '\\0') {\n\t  blocks_str = argv&#91;c] + 10;\n\t  blocks = getlonglong(blocks_str);\n\t} else if(c + 1 &lt; argc) {\n\t  blocks_str = argv&#91;c + 1];\n\t  blocks = getlonglong(blocks_str);\n\t  c++;\n\t}\n\tblocks_set = 1;\n\n      } else if(!strcmp(\"--copyright\", argv&#91;c]) ||\n\t !strcmp(\"--version\", argv&#91;c])) {\n\tnewressu_version();\n#ifdef SHA256\n\tfprintf(stderr,\"\\nsha256(\");\n\tfor(int c = 0; c &lt; HashLen; c++) {\n\t  fprintf(stderr, \"%02x\", programfiledigest&#91;c]);\n\t}\n#endif\n\tfprintf(stderr, \")\\n\\n\");\n\thelp = 0;\n\texit(1);\n\t\n      } else if(!strcmp(\"--webversion\", argv&#91;c])) {\n\tfprintf(stderr, \"%s\", programname); \/\/ touch these outside MAIN\n\tfprintf(stderr,\", sha256(\");\n\tfor(int c = 0; c &lt; HashLen; c++) {\n\t  fprintf(stderr, \"%02x\", programfiledigest&#91;c]);\n\t}\n\tfprintf(stderr,\")\\n\");\n\texit(0);\n\n      } else if(!strcmp(\"--lineno\", argv&#91;c])) {\n\tslineno = !slineno; \/\/ print line number\n\t\n      } else if(!strcmp(\"--crlf\", argv&#91;c])) {\n\tscrlf = !scrlf;\n\tslineno = 0;\n\n#ifdef DEBUG19\t\n      } else if(!strcmp(\"--int\", argv&#91;c])) {\n\tflagint = !flagint;\n\n#endif\n      } else if(!strcmp(\"--rand\", argv&#91;c])) {\n\tdigits = \"0123456789\";\n\tsspace = 2;\n\tsnewline = 5;\n\tslineno = 1; \/\/ print line number\n\twords = 10;\n\tchars = 0;\n\tlimit = 100000;\n\t\/\/size = 5;\n\t\/\/lines = 20000;\n\t\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(!strncmp(\"--lim\", argv&#91;c], 5)) { \/\/ limit of word\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\t\/\/fprintf(stdout,\"limit:%lu, %ld bytes\\n\", limit, sizeof(limit));\n\tif(sspace &lt; 1 ) \/\/ 23.6.2021\n\t  sspace = 1;\n\n      } else if(!strncmp(\"--size\", argv&#91;c], 6)) { \/\/ size of word\n\tif(isdigit(*(argv&#91;c] + 6))) {\n\t  size = atoi(argv&#91;c] + 6);\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\n      } else if(!strncmp(\"-s\", argv&#91;c], 2)) { \/\/ size of word\n\tif(isdigit(*(argv&#91;c] + 2))) {\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\n      } else if(!strncmp(\"--bits\", argv&#91;c], 6)) {\n\tif(isdigit(*(argv&#91;c] + 6))) {\n\t  ressut_bits1_needed = atoi(argv&#91;c] + 6);\n\t} else if(c + 1 &lt; argc) {\n\t  ressut_bits1_needed = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\t\n\n      } else if(!strncmp(\"--bytes\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\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(\"--words\", argv&#91;c], 7)) { \/\/ words per line\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  words = atoi(argv&#91;c] + 7);\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\tchars = 0;\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"-w\", argv&#91;c], 2)) { \/\/ words per line\n\tif(isdigit(*(argv&#91;c] + 2))) {\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\tchars = 0;\n\tscreen = 0;\n\t\n      } else if(!strcmp(\"-c*\", argv&#91;c])) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\twords = 0;\n\n      } else if(!strcmp(\"-l*\", argv&#91;c])) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tlines = w.ws_row-1;\n\n      } else if(!strcmp(\"--chars*\", argv&#91;c])) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\twords = 0;\n\n      } else if(!strcmp(\"--lines*\", argv&#91;c])) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tlines = w.ws_row-1;\n\n      } else if(!strncmp(\"--screen\", argv&#91;c],8)) { \/\/ screenful\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\tlines = w.ws_row-1;\n\twords = 0;\n\tscreen = 1;\n\t\n      } else if(!strncmp(\"--chars\", argv&#91;c], 7)) {  \/\/ characters per line\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  chars = atoi(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  chars = atoi(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tif(chars &lt; 1)\n\t  chars = 72;\n\twords = 0;\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"-c\", argv&#91;c], 2)) {  \/\/ characters per line\n\tif(isdigit(*(argv&#91;c] + 2))) {\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\tif(chars &lt; 1)\n\t  chars = 72;\n\twords = 0;\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"--lines\",argv&#91;c], 7)) { \/\/ lines\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  lines = atoll(argv&#91;c] + 7);\n\t} else if(c + 1 &lt; argc) {\n\t  lines = atoll(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"-l\",argv&#91;c], 2)) { \/\/ lines\n\tif(isdigit(*(argv&#91;c] + 2))) {\n\t  lines = atoll(argv&#91;c] + 2);\n\t} else if(c + 1 &lt; argc) {\n\t  lines = atoll(argv&#91;c + 1]);\n\t  c++;\n\t}\n\tscreen = 0;\n\t\n      } else if(!strcmp(\"--otp1\", argv&#91;c]) || \/\/ see: one time pad\n\t\t!strcmp(\"--otp5n\", argv&#91;c]) || \/\/ digits length 5\n\t\t!strcmp(\"--onetimepad1\", argv&#91;c])) {\t\t\n\tdigits = \"0123456789\";\n\tsspace = 1;\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--otp2\", argv&#91;c]) || \/\/ uppercase alpha length 5\n\t\t!strcmp(\"--otp5a\", argv&#91;c]) ||\t\t\n\t\t!strcmp(\"--onetimepad2\", argv&#91;c]) ||\n\t\t!strcmp(\"--diana\", argv&#91;c]) ) { \/\/ see: diana cipher, diana table\n\tdigits = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\tsspace = 1;\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--otp3\", argv&#91;c]) || \/\/ uppercase alpha length 4\n\t\t!strcmp(\"--otp4a\", argv&#91;c]) ||\t\t\n\t\t!strcmp(\"--onetimepad3\", argv&#91;c])) {\n\tdigits = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\tsspace = 1;\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 0;\n\n      } else if(!strncmp(\"--base\", argv&#91;c], 6)) {\n\n\tif(isdigit(*(argv&#91;c] + 6))) {\n\t  newressu_base(atoi(argv&#91;c] + 6));\n\t} else if(c + 1 &lt; argc) {\n\t  newressu_base(atoi(argv&#91;c + 1]));\n\t  c++;\n\t}\n\tif(base &lt; 2 || base > 64) {\n\t  fprintf(stderr,\"%s: base must be from 2 to 64 (%s)\\n\", procname, argv&#91;c]);\n\t  exit(2);\n\t}\n      } else if(!strncmp(\"--BASE\", argv&#91;c], 6)) {\n\n\tif(isdigit(*(argv&#91;c] + 6))) {\n\t  uppercase = 1;\n\t  newressu_base(atoi(argv&#91;c] + 6));\n\t} else if(c + 1 &lt; argc) {\n\t  uppercase = 1;\n\t  newressu_base(atoi(argv&#91;c + 1]));\n\t  c++;\n\t}\n\tif(base &lt; 2 || base > 64) {\n\t  fprintf(stderr,\"%s: base must be from 2 to 64 (%s)\\n\", procname, argv&#91;c]);\n\t  exit(2);\n\t}\n\t\n      } else if(!strcmp(\"-b\", argv&#91;c]) ||\n\t\t!strcmp(\"--bin\", argv&#91;c]) ||\n\t\t!strcmp(\"--1bit\", argv&#91;c]) ||\n\t\t!strcmp(\"--1bits\", argv&#91;c])) {\n\n\tnewressu_base(2);\n\t\n      } else if(!strcmp(\"--2bits\", argv&#91;c])) {\n\n\tnewressu_base(4);\n\n      } else if(!strcmp(\"-o\", argv&#91;c]) ||\n\t\t!strcmp(\"--oct\", argv&#91;c]) ||\n\t\t!strcmp(\"--3bits\", argv&#91;c]) ) {\n\n\tnewressu_base(8);\n\n      } else if(!strcmp(\"-d\", argv&#91;c]) ||\n\t\t!strcmp(\"--dec\", argv&#91;c])) {\n\n\tnewressu_base(10);\n\n      } else if(!strcmp(\"-x\", argv&#91;c]) ||\n\t\t!strcmp(\"--hex\", argv&#91;c]) ||\n\t\t!strcmp(\"--4bits\", argv&#91;c])) {\n\n\tnewressu_base(16);\n\n      } else if(!strcmp(\"-X\", argv&#91;c]) ||\n\t\t!strcmp(\"--HEX\", argv&#91;c]) ||\n\t\t!strcmp(\"--4BITS\", argv&#91;c])) {\n\n\tnewressu_base(16);\n\tuppercase = 1;\n\n      } else if(!strcmp(\"-5\", argv&#91;c]) ||\n\t\t!strcmp(\"--5bits\", argv&#91;c])) {\n\n\tnewressu_base(32);\n\tbase = 32;\n\t\n      } else if(!strcmp(\"--5BITS\", argv&#91;c])) {\n\n\tnewressu_base(32);\n\tuppercase = 1;\n\t\n      } else if(!strcmp(\"-2\", argv&#91;c]) ||\n\t\t!strcmp(\"--6bits\", argv&#91;c])) {\n\n\tnewressu_base(64);\n\t\n      } else if(!strcmp(\"-1\", argv&#91;c])) {\n\tdigits =\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--numeric\", argv&#91;c]) ||\n\t\t!strcmp(\"-11\", argv&#91;c])) {\n\tdigits =\n\t  \"0123456789\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 10;\n\n      } else if(\/\/ !strcmp(\"--ALPHA\", argv&#91;c]) ||\n\t\t!strcmp(\"--LATIN\", argv&#91;c]) ||\n\t\t!strcmp(\"-12\", argv&#91;c]) ) {\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\n      } else if( \/\/!strcmp(\"--alpha\", argv&#91;c]) ||\n\t\t!strcmp(\"--latin\", argv&#91;c]) ||\n\t\t!strcmp(\"-13\", argv&#91;c])) {\n\tdigits =\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"-13v1\", argv&#91;c])) {\n\tdigits =\n\t  \"abcdefghijklmnopqrstuvwxyz\" \\\n\t  \"aeiouy\"; \/\/ extra vowels\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"-13v2\", argv&#91;c])) {\n\tdigits =\n\t  \"abcdefghijklmnopqrstuvwxyz\"\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\"; \/\/ extra vowels\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"-13v3\", argv&#91;c])) {\n\tdigits =\n\t  \"abcdefghijklmnopqrstuvwxyz\"\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\"; \/\/ extra vowels\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"-13v4\", argv&#91;c])) {\n\tdigits =\n\t  \"abcdefghijklmnopqrstuvwxyz\"\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\" \/\/ extra vowels\n\t  \"aeiouy\"; \/\/ extra vowels\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 0;\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\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"-9\", argv&#91;c])) {\n\tdigits =\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--dnk\", argv&#91;c]) || \/\/ Danish alphabet\n\t\t!strcmp(\"--nor\", argv&#91;c])) { \/\/ Norwegian alphabet\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--fin\", argv&#91;c]) || \/\/ Finnish alphabet\n\t\t!strcmp(\"--swe\", argv&#91;c])) { \/\/ Swedish alphabet\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--rus\", argv&#91;c])) { \/\/ Russian alphabet\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\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--est\", argv&#91;c])) { \/\/ Estonian alphabet\n\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRS\u0160Z\u017dTUVW\u00d5\u00c4\u00d6\u00dcXY\" \\\n\t  \"abcdefghijklmnopqrs\u0161z\u017etuvw\u00f5\u00e4\u00f6\u00fcxy\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n  \n      } else if(!strcmp(\"--ltu\", argv&#91;c])) { \/\/ Lithuanian alphabet\n\tdigits =\n\t  \"A\u0104BC\u010cDE\u0118\u0116FGHI\u012eYJKLMNOPRS\u0160TU\u0172\u016aVZ\u017d\" \\\n\t  \"a\u0105bc\u010dde\u0119\u0117fghi\u012fyjklmnoprs\u0161tu\u0173\u016bvz\u017e\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--lva\", argv&#91;c])) { \/\/ Latvian alphabet\n\tdigits =\n\t  \"A\u0100BC\u010cDE\u0112FG\u0122HI\u012aJK\u0136L\u013bMN\u0145OPRS\u0160TU\u016aVZ\u017d\" \\\n\t  \"a\u0101bc\u010dde\u0113fg\u0123hi\u012bjk\u0137l\u013cmn\u0146oprs\u0161tu\u016bvz\u017e\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--fra\", argv&#91;c]) \/\/ French alphabet\n\t\t||!strcmp(\"--gbr\", argv&#91;c]) \/\/ Great Britain alphabet\n\t\t||!strcmp(\"--usa\", argv&#91;c]) \/\/ United States alphabet\n\t\t||!strcmp(\"--ita\", argv&#91;c]) \/\/ Italian alphabet\n\t\t||!strcmp(\"--eng\", argv&#91;c]) \/\/ English alphabet\n\t\t) {\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--deu\", argv&#91;c])) { \/\/ Deutsch alphabet\n\tdigits =\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u1e9e\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00fc\u00df\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--grc\", argv&#91;c])) { \/\/ Greek alphabet\n\tdigits =\n\t  \"\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\" \\\n\t  \"\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--jp\", argv&#91;c])) { \/\/ all Japanese alphabets\n\n\tdigits = NULL;\n\tdigits_add_string(&amp;digits,\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\");\n\tdigits_add_string(&amp;digits,\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\");\n\tdigits_add_limits(&amp;digits, 0x4e00, 0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--jp1\", argv&#91;c]) \/\/ Japanese hiragana alphabet\n\t     || !strcmp(\"--hir\", argv&#91;c])) {\n\tdigits =\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\";\n\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--jp2\", argv&#91;c]) \/\/ Japanese katakana alphabet\n\t     || !strcmp(\"--kat\", argv&#91;c])) {\n\tdigits =\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\";\n\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cn\", argv&#91;c]) \/\/ Chinese alphabet \n\t     || !strcmp(\"--jp3\", argv&#91;c]) \/\/ Japanese kanji alphabet\n\t     || !strcmp(\"--kan\", argv&#91;c])) { \/\/ Japanese kanji alphabet\n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits, 0x4e00, 0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--kor\", argv&#91;c])) { \/\/ Korean alphabet \n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits,0xac00,0xd7a3);   \/\/ Hangul Syllables (AC00\u2013D7A3)\n\t\/\/digits_add_limits(&amp;digits,0x1100,0x11ff); \/\/ Hangul Jamo (1100\u201311FF)\n\t\/\/digits_add_limits(&amp;digits,0x3130,0x318f); \/\/ Hangul Compatibility Jamo (3130\u2013318F)\n\t\/\/digits_add_limits(&amp;digits,0xa960,0xa97f); \/\/ Hangul Jamo Extended-A (A960\u2013A97F)\n\t\/\/digits_add_limits(&amp;digits,0xd7b0,0xd7ff); \/\/Hangul Jamo Extended-B (D7B0\u2013D7FF)\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--ind\", argv&#91;c]) \/\/ not ready\n\t     || !strcmp(\"--hin\", argv&#91;c])) { \/\/ Hindi alphabet\n\t\/\/unsigned char *signs = \"\u0900\u0901\u0902\u0903\u093a\u093b\u093c\u093d\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d\u094e\u094f\u0955\u0956\u0957\u0962\u0963\u0951\u0952\u0953\u0954\";\n\tdigits =\n\t  \"\u0904\u0905\u0906\u0907\u0908\u0909\u090a\u090b\u090c\u090d\u090e\u090f\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\u091b\u091c\u091d\u091e\u091f\u0920\u0921\u0922\u0923\"\n\t  \"\u0924\u0925\u0926\u0927\u0928\u0929\u092a\u092b\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093d\u0950\u0958\u0959\u095a\u095b\u095c\"\n\t  \"\u095d\u095e\u095f\u0960\u0961\u0964\u0965\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0970\u0971\u0972\u0973\u0974\u0975\u0976\u0977\u0978\u0979\u097a\u097b\u097c\u097d\u097e\"\n\t  \"\u097f\"; \/\/ 97 characters\n\n\t\/\/digits_add_limits(&amp;digits,0x900,0x97f);   \/\/ Hindi (0900-097f)\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--heb\", argv&#91;c])) { \/\/ hebrew\n\n\t\/\/ \u0590\u0591\u0592\u0593\u0594\u0595\u0596\u0597\u0598\u0599\u059a\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05c4\u05c5\u05c6\u05c7\u05c8\u05c9\u05ca\u05cb\u05cc\u05cd\u05ce\u05cf\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05eb\u05ec\u05ed\u05ee\u05ef\u05f0\u05f1\u05f2\u05f3\u05f4\u05f5\u05f6\u05f7\u05f8\u05f9\u05fa\u05fb\u05fc\u05fd\u05fe\u05ff\n\t\n\tdigits = \"\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pho\", argv&#91;c])) { \/\/ phoenician alphabet, (fi \"foinikialaiset aakkoset\")\n\n\t\/\/phoenician: \ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd03\ud802\udd04\ud802\udd05\ud802\udd06\ud802\udd07\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd0b\ud802\udd0c\ud802\udd0d\ud802\udd0e\ud802\udd0f\ud802\udd10\ud802\udd11\ud802\udd12\ud802\udd13\ud802\udd14\ud802\udd15\ud802\udd16\ud802\udd17\ud802\udd18\ud802\udd19\ud802\udd1a\ud802\udd1b\ud802\udd1c\ud802\udd1d\ud802\udd1e\ud802\udd1f\n\tdigits = \"\ud802\udd00\ud802\udd01\ud802\udd02\ud802\udd03\ud802\udd04\ud802\udd05\ud802\udd06\ud802\udd07\ud802\udd08\ud802\udd09\ud802\udd0a\ud802\udd0b\ud802\udd0c\ud802\udd0d\ud802\udd0e\ud802\udd0f\ud802\udd10\ud802\udd11\ud802\udd12\ud802\udd13\ud802\udd14\ud802\udd15\ud802\udd16\ud802\udd17\ud802\udd18\ud802\udd19\ud802\udd1a\ud802\udd1b\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--som\", argv&#91;c]) ||\n\t\t!strcmp(\"--SOM\", argv&#91;c]) ||\n\t\t!strcmp(\"--SO\", argv&#91;c])) { \/\/ Somalia alphabet\n\n#define aNEWSOM 2\n\t\n#ifdef NEWSOM\n\tdigits = NULL;\n\t\/\/ A, B, T, J, X, KH, D, R, S, SH, DH, C, G, F, Q, K, L, M, N, W, H, Y, E, and O\n\tdigits_add_string(&amp;digits, \"A;\");\n\tdigits_add_string(&amp;digits, \"B;\");\n\tdigits_add_string(&amp;digits, \"T;\");\n\tdigits_add_string(&amp;digits, \"J;\");\n\tdigits_add_string(&amp;digits, \"X;\");\n\tdigits_add_string(&amp;digits, \"KH;\");\n\tdigits_add_string(&amp;digits, \"D;\");\n\tdigits_add_string(&amp;digits, \"R;\");\n\tdigits_add_string(&amp;digits, \"S;\");\n\tdigits_add_string(&amp;digits, \"SH;\");\n\tdigits_add_string(&amp;digits, \"DH;\");\n\tdigits_add_string(&amp;digits, \"C;\");\n\tdigits_add_string(&amp;digits, \"G;\");\n\tdigits_add_string(&amp;digits, \"F;\");\n\tdigits_add_string(&amp;digits, \"Q;\");\n\tdigits_add_string(&amp;digits, \"K;\");\n\tdigits_add_string(&amp;digits, \"L;\");\n\tdigits_add_string(&amp;digits, \"M;\");\n\tdigits_add_string(&amp;digits, \"N;\");\n\tdigits_add_string(&amp;digits, \"W;\");\n\tdigits_add_string(&amp;digits, \"H;\");\n\tdigits_add_string(&amp;digits, \"Y;\");\n\tdigits_add_string(&amp;digits, \"E;\");\n\tdigits_add_string(&amp;digits, \"O;\");\n\n\tflagdigits = 2; \/\/ semicolon separated (flags)\n\t\n#else\n\t\/\/ missing KH SH DH\n\tdigits = \"ABTJXDRSCGFQKLMNWHYEO\";\n#endif\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--braille\", argv&#91;c])) { \/\/ Braille alphabet\n\tdigits = \/\/ 0x2800 - 0x2900\n\t  \"\u2800\u2801\u2802\u2803\u2804\u2805\u2806\u2807\u2808\u2809\u280a\u280b\u280c\u280d\u280e\u280f\u2810\u2811\u2812\u2813\u2814\u2815\u2816\u2817\u2818\u2819\u281a\u281b\u281c\u281d\u281e\u281f\u2820\u2821\u2822\u2823\u2824\u2825\u2826\u2827\u2828\u2829\u282a\u282b\u282c\u282d\u282e\u282f\u2830\u2831\u2832\u2833\u2834\u2835\u2836\u2837\u2838\u2839\u283a\u283b\u283c\u283d\u283e\u283f\"\n\t  \"\u2840\u2841\u2842\u2843\u2844\u2845\u2846\u2847\u2848\u2849\u284a\u284b\u284c\u284d\u284e\u284f\u2850\u2851\u2852\u2853\u2854\u2855\u2856\u2857\u2858\u2859\u285a\u285b\u285c\u285d\u285e\u285f\u2860\u2861\u2862\u2863\u2864\u2865\u2866\u2867\u2868\u2869\u286a\u286b\u286c\u286d\u286e\u286f\u2870\u2871\u2872\u2873\u2874\u2875\u2876\u2877\u2878\u2879\u287a\u287b\u287c\u287d\u287e\u287f\"\n\t  \"\u2880\u2881\u2882\u2883\u2884\u2885\u2886\u2887\u2888\u2889\u288a\u288b\u288c\u288d\u288e\u288f\u2890\u2891\u2892\u2893\u2894\u2895\u2896\u2897\u2898\u2899\u289a\u289b\u289c\u289d\u289e\u289f\u28a0\u28a1\u28a2\u28a3\u28a4\u28a5\u28a6\u28a7\u28a8\u28a9\u28aa\u28ab\u28ac\u28ad\u28ae\u28af\u28b0\u28b1\u28b2\u28b3\u28b4\u28b5\u28b6\u28b7\u28b8\u28b9\u28ba\u28bb\u28bc\u28bd\u28be\u28bf\"\n\t  \"\u28c0\u28c1\u28c2\u28c3\u28c4\u28c5\u28c6\u28c7\u28c8\u28c9\u28ca\u28cb\u28cc\u28cd\u28ce\u28cf\u28d0\u28d1\u28d2\u28d3\u28d4\u28d5\u28d6\u28d7\u28d8\u28d9\u28da\u28db\u28dc\u28dd\u28de\u28df\u28e0\u28e1\u28e2\u28e3\u28e4\u28e5\u28e6\u28e7\u28e8\u28e9\u28ea\u28eb\u28ec\u28ed\u28ee\u28ef\u28f0\u28f1\u28f2\u28f3\u28f4\u28f5\u28f6\u28f7\u28f8\u28f9\u28fa\u28fb\u28fc\u28fd\u28fe\u28ff\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--got\", argv&#91;c])) { \/\/ Gothic alphabet\n        digits=\n          \"\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d\ud800\udf3e\ud800\udf3f\"\n          \"\ud800\udf40\ud800\udf41\ud800\udf42\ud800\udf43\ud800\udf44\ud800\udf45\ud800\udf46\ud800\udf47\ud800\udf48\ud800\udf49\ud800\udf4a\";\n\n      } else if(!strcmp(\"---champagne\", argv&#91;c])) { \/\/ Gothic alphabet\n        digits = \"\ud83c\udf7e\ud83e\udd42\ud83e\udd42\ud83e\udd42\ud83e\udd42\"; \/\/ \ud83e\udd64\ud83e\udd64\ud83e\udd64\ud83e\udd64\ud83e\udd64\ud83e\udd64\ud83e\udd64\ud83e\udd64\"; \/\/ \n\tcharspaces = 0;\n\tcharwidth = 2;\n        size = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cards\", argv&#91;c])) {\n\tdigits=\n\t  \"\ud83c\udca1\ud83c\udca2\ud83c\udca3\ud83c\udca4\ud83c\udca5\ud83c\udca6\ud83c\udca7\ud83c\udca8\ud83c\udca9\ud83c\udcaa\ud83c\udcab\ud83c\udcad\ud83c\udcae\"\n\t  \"\ud83c\udcb1\ud83c\udcb2\ud83c\udcb3\ud83c\udcb4\ud83c\udcb5\ud83c\udcb6\ud83c\udcb7\ud83c\udcb8\ud83c\udcb9\ud83c\udcba\ud83c\udcbb\ud83c\udcbd\ud83c\udcbe\"\n\t  \"\ud83c\udcc1\ud83c\udcc2\ud83c\udcc3\ud83c\udcc4\ud83c\udcc5\ud83c\udcc6\ud83c\udcc7\ud83c\udcc8\ud83c\udcc9\ud83c\udcca\ud83c\udccb\ud83c\udccd\ud83c\udcce\"\n\t  \"\ud83c\udcd1\ud83c\udcd2\ud83c\udcd3\ud83c\udcd4\ud83c\udcd5\ud83c\udcd6\ud83c\udcd7\ud83c\udcd8\ud83c\udcd9\ud83c\udcda\ud83c\udcdb\ud83c\udcdd\ud83c\udcde\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cardsuits\", argv&#91;c])) {\n\tdigits=\n\t  \"\u2660\u2661\u2662\u2663\u2664\u2665\u2666\u2667\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--chessmen\", argv&#91;c])) {\n\tdigits=\n\t  \"\u2654\u2655\u2656\u2657\u2658\u2659\u265a\u265b\u265c\u265d\u265e\u265f\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--dice\", argv&#91;c])) {\n\tdigits=\n\t  \"\u2680\u2681\u2682\u2683\u2684\u2685\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--mahjong\", argv&#91;c])) {\n\tdigits= \/\/ removed \ud83c\udc04 &amp; \ud83c\udc2b\n\t  \"\ud83c\udc00\ud83c\udc01\ud83c\udc02\ud83c\udc03\ud83c\udc05\ud83c\udc06\" \\\n\t  \"\ud83c\udc07\ud83c\udc08\ud83c\udc09\ud83c\udc0a\ud83c\udc0b\ud83c\udc0c\ud83c\udc0d\ud83c\udc0e\ud83c\udc0f\" \\\n\t  \"\ud83c\udc10\ud83c\udc11\ud83c\udc12\ud83c\udc13\ud83c\udc14\ud83c\udc15\ud83c\udc16\ud83c\udc17\ud83c\udc18\" \\\n\t  \"\ud83c\udc19\ud83c\udc1a\ud83c\udc1b\ud83c\udc1c\ud83c\udc1d\ud83c\udc1e\ud83c\udc1f\ud83c\udc20\ud83c\udc21\" \\\n\t  \"\ud83c\udc22\ud83c\udc23\ud83c\udc24\ud83c\udc25\ud83c\udc26\ud83c\udc27\ud83c\udc28\ud83c\udc29\ud83c\udc2a\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 5;\n\ttype = 0;\n\n      } else if(!strcmp(\"--dna\", argv&#91;c])) {\n\tdigits=\n\t  \"acgt\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--DNA\", argv&#91;c])) {\n\tdigits=\n\t  \"ACGT\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--pattern1\", argv&#91;c])) {\n\tdigits=\n\t  \"\u258c\u2599\u2584\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern2\", argv&#91;c])) {\n\tdigits=\n\t  \"\u25dc\u25dd\u25de\u25df\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern3\", argv&#91;c])) {\n\tdigits=\n\t  \"\\\\\/\";\n\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern4\", argv&#91;c])) {\n\tdigits=\n\t  \"\u25f8\u25f9\u25fa\u25ff\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern5\", argv&#91;c])) {\n\tdigits=\n\t  \"\u25a7\u25a8\";\n\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--alnum\", argv&#91;c]) || \/\/ 9.5.2021 JariK\n\t        !strcmp(\"--alpha\", argv&#91;c]) ||\n\t        !strcmp(\"--digit\", argv&#91;c]) ||\n\t        !strcmp(\"--graph\", argv&#91;c]) ||\n\t        !strcmp(\"--lower\", argv&#91;c]) ||\n\t        !strcmp(\"--print\", argv&#91;c]) ||\n\t        !strcmp(\"--punct\", argv&#91;c]) ||\n\t        !strcmp(\"--upper\", argv&#91;c]) ||\n\t\t!strcmp(\"--xdigit\", argv&#91;c])) {\n\tunsigned char *p = digitstemp;\n\tfor(d = 0; d &lt; 256; d++) {\n\t  if((!strcmp(\"--alnum\", argv&#91;c]) &amp;&amp; isalnum(d)) ||\n\t     (!strcmp(\"--alpha\", argv&#91;c]) &amp;&amp; isalpha(d)) ||\n\t     (!strcmp(\"--digit\", argv&#91;c]) &amp;&amp; isdigit(d)) ||\n\t     (!strcmp(\"--graph\", argv&#91;c]) &amp;&amp; isgraph(d)) ||\n\t     (!strcmp(\"--lower\", argv&#91;c]) &amp;&amp; islower(d)) ||\n\t     (!strcmp(\"--print\", argv&#91;c]) &amp;&amp; isprint(d)) ||\n\t     (!strcmp(\"--punct\", argv&#91;c]) &amp;&amp; ispunct(d)) ||\n\t     (!strcmp(\"--upper\", argv&#91;c]) &amp;&amp; isupper(d)) ||\n\t     (!strcmp(\"--xdigit\", argv&#91;c]) &amp;&amp; isxdigit(d))) {\n\t    *p++ = d;\n\t  }\n\t}\n\t*p = '\\0';\n\tdigits = digitstemp;\n\tsize = 5;\n\ttype = 0;\n\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 || utf8characters(digits) &lt; 2) {\n\t  fprintf(stderr,\"%s: not enough digits \\\"%s\\\"\\n\", procname, argv&#91;c]);\n\t}\n\tsize = 1;\n\n#ifdef USE_TIMER\n      } else if(!strcmp(\"--timer\", argv&#91;c])) {\n\ttimer = 1;\n\n#endif\n      } else if(!strcmp(\"--clockstream\", argv&#91;c])) { \/\/ clockstream\n\tinput = INPUT_CLOCK;\n\tinput_str = argv&#91;c] + 2;\n\t\n      } else if(!strcmp(\"--test\", argv&#91;c])) { \/\/ test generator\n\tinput = INPUT_TEST;\n\tinput_str = argv&#91;c] + 2;\n\t\n      } else if(!strcmp(\"--ressu\", argv&#91;c])) {\n\tinput = INPUT_RESSU;\n\tinput_str = argv&#91;c] + 2;\n\t\n      } else if(!strcmp(\"--pseudoressu\", argv&#91;c])) {\n\tinput = INPUT_PSEUDORESSU;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--ressutwist\", argv&#91;c]) \/\/ JariK 2023\n\t\t|| !strcmp(\"--ressuwtwist\", argv&#91;c])\n\t        || !strcmp(\"--twist\", argv&#91;c]) ) {\n\tinput = INPUT_RESSUTWIST;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--fast\", argv&#91;c])\n\t\t|| !strcmp(\"--fastressu\", argv&#91;c]) ) {\n\tinput = INPUT_FASTRESSU;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--single\", argv&#91;c])\n\t\t|| !strcmp(\"--singleressu\", argv&#91;c]) ) {\n\tinput = INPUT_SINGLERESSU;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--stream\", argv&#91;c])) {\n\tinput = INPUT_STREAM;\n\tinput_str = argv&#91;c] + 2;\n\t\n      } else if(!strncmp(\"--key\", argv&#91;c], 5)) {\n\tkey = NULL;\n\tif(*(argv&#91;c] + 5) != '\\0') {\n\t  key = argv&#91;c] + 5;\n\t} else if(c + 1 &lt; argc) {\n\t  key = argv&#91;c + 1];\n\t  c++;\n\t}\n\tif(key == NULL || utf8characters(key) &lt; 1) {\n\t  fprintf(stderr,\"%s: not enough key characters \\\"%s\\\"\\n\", procname, argv&#91;c]);\n\t  exit(1);\n\t}\n\t\/\/size = 1;\n\n      } else if(!strncmp(\"--fixedclock\", argv&#91;c], 12)) {\n\tif(*(argv&#91;c] + 12) != '\\0' &amp;&amp; atoi(argv&#91;c] + 12) > 1) {\n\t  fixedclockchainlength = atoi(argv&#91;c] + 12);\n\t  fixedclock = 1;\n\t} else if(c + 1 &lt; argc &amp;&amp; atoi(argv&#91;c + 1]) > 1) {\n\t  fixedclockchainlength = atoi(argv&#91;c + 1]);\n\t  fixedclock = 1;\n\t  c++;\n\t} else {\n\t  fixedclock = !fixedclock;\n\t}\n\n\tif(fixedclockchainlength &lt; 5 ||\n\t   fixedclockchainlength > 255)\n\t  fixedclockchainlength = FIXEDCLOCKCHAINLENGTH;\n\n      } else if(!strncmp(\"--depth\", argv&#91;c], 7)) {\n\tif(isdigit(*(argv&#91;c] + 7))) {\n\t  depth = atoi(argv&#91;c] + 7);\n\n\t} else if(c + 1 &lt; argc &amp;&amp; isdigit(*(argv&#91;c + 1]))) {\n\t  depth = atoi(argv&#91;c + 1]);\n\t  c++;\n\t  \n\t} else {\n\t  depth = MAX_DEPTH;\n\t}\n\n\tif(depth &lt; 0 || depth > MAX_DEPTH) {\n\t  fprintf(stderr,\"%s: --depth must be between 0 and %d(MAX_DEPTH)\\n\",\n\t\t  procname, MAX_DEPTH);\n\t  exit(2);\n\t}\n\n\tfprintf(stderr,\"depth:%d\\n\", depth);\n\n      } else if(!strcmp(\"--copyreverse\", argv&#91;c])) {\n\tcopyreverse = !copyreverse;\n\t\n      } else if(!strcmp(\"--verbose\", argv&#91;c])) {\n\tverbose = !verbose;\n\t\n      } else if(!strcmp(\"--statline\", argv&#91;c])) {\n\tprint_statline = !print_statline;\n\n#ifdef FORT\n      } else if(!strcmp(\"--fort\", argv&#91;c])) {\n\tinput = INPUT_FORT;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--fortxor\", argv&#91;c])) {\n\tinput = INPUT_FORTXOR;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--fortverbose\", argv&#91;c])) {\n\tverbose = !verbose;\n\n      } else if(!strcmp(\"--fortuseweb\", argv&#91;c])) {\n\tfort_use_web = !fort_use_web;\n\t\n#endif\n#ifdef USE_RDRAND\n      } else if(!strcmp(\"--rdrand\", argv&#91;c])) {\n\tinput = INPUT_RDRAND;\n\tinput_str = argv&#91;c] + 2;\n\n#endif\n#ifdef USE_RDSEED\n      } else if(!strcmp(\"--rdseed\", argv&#91;c])) {\n\tinput = INPUT_RDSEED;\n\tinput_str = argv&#91;c] + 2;\n\n#endif\n      } else if(!strcmp(\"--urandom\", argv&#91;c])) {\n\tinput = INPUT_URANDOM;\n\tinput_str = argv&#91;c] + 2;\n\n#ifdef USE_RANDOM\n      } else if(!strcmp(\"--random\", argv&#91;c])) {\n\tinput = INPUT_RANDOM;\n\tinput_str = argv&#91;c] + 2;\n\n#endif\n      } else if(!strcmp(\"--dummy\", argv&#91;c])) {\n\tinput = INPUT_DUMMY;\n\tinput_str = argv&#91;c] + 2;\n\n      } else if(!strcmp(\"--flags\", argv&#91;c])) { \/\/ not ready\n\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\tflagdigits = 1; \/\/ semicolon separated (flags)\n\t\n\t\/\/ code after command line parameter loop\n\t\n      } else if(!strcmp(\"--all\", argv&#91;c])) { \/\/ not ready\n\tif(flagsinit) {\n\t  idsall = 1;\n\t  newressu_toggleflag(\"ALL\");\n\t  flagsinit = 0;\n\t}\n\tflagdigits = 1; \/\/ semicolon separated (flags)\n\t\n      } else {\n\tok = 0;\n      }\n\n      unsigned char buffer&#91;32];\n\n      int ok2 = 0;\n      \n      \/\/ command line parameters for flags\n      \n      if(!strncmp(argv&#91;c], \"--\", 2)) {\n\tif(flagsinit) {\n\t  idsall = 0;\n\t  newressu_toggleflag(buffer);\n\t  flagsinit = 0;\n\t}\n\tstrcpy(buffer, argv&#91;c] + 2); \/\/ as is, skip dashes\n\tif(newressu_toggleflag(buffer) == 1)\n\t  ok2 = 1;\n\telse {\n\t  strtolower(buffer); \/\/ all letters lowercase\n\t  if(newressu_toggleflag(buffer) == 1)\n\t    ok2 = 1;\n\t  else {\n\t    buffer&#91;0] = toupper(buffer&#91;0]); \/\/ first letter uppercase\n\t    if(newressu_toggleflag(buffer) == 1)\n\t      ok2 = 1;\n\t    else {\n\t      strtoupper(buffer); \/\/ all letters uppercase\n\t      if(newressu_toggleflag(buffer) == 1)\n\t\tok2 = 1;\n\t    }\n\t  }\n\t}\n      }\n      if(flagflags &amp;&amp; ok == 0 &amp;&amp; ok2 == 0) {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n      if(!flagflags &amp;&amp; ok == 0 &amp;&amp; ok2 == 0) {\n\tfprintf(stderr,\"%s: invalid option %s\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n      if(!flagflags &amp;&amp; ok == 0 &amp;&amp; ok2 == 1) {\n\tfprintf(stderr,\"%s: invalid option '%s' without --flags\\n\", procname, argv&#91;c]);\n\texit(1);\n      }\n    } \/\/ if(!strncmp\n  } \/\/ for(c = 0\n\n  if(size == -1 &amp;&amp; base != -1) {\n    if(base == 2)\n      size = 8;\n    else if(base == 8)\n      size = 3;\n    else if(base == 10)\n      size = 5;\n    else if(base == 16)\n      size = 4;\n    else\n      size = 8;\n  }\n\n  if(size == -1 &amp;&amp; base == -1)\n    size = 5;\n  \n  if(base != -1) {\n    digitsext = digits;\n    charspaces = 0;\n    charwidth = 1;\n  }\n  \n  if(flagflags) {\n\n    digits = NULL;\n    flagdigits = 1; \/\/ semicolon separated (flags)\n\n    for(d = 0; d &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); d++) {\n      unsigned char buffer&#91;32];\n      if(flagids&#91;d] == 1) {\n\tstrcpy(buffer,idsflags&#91;d].id);\n\tstrcat(buffer,\";\");\n\tdigits_add_string(&amp;digits, buffer);\n      }\n    }\n\n    if(digits == NULL)\n      digits = \"\ud83c\uddeb\ud83c\uddee;\";\n    else\n      digitsext = digits;\n\n    \/\/digits = \"\ud83c\udde6\ud83c\udde7\ud83c\udde8\ud83c\udde9\ud83c\uddea\ud83c\uddeb\ud83c\uddec\ud83c\udded\ud83c\uddee\ud83c\uddef\ud83c\uddf0\ud83c\uddf1\ud83c\uddf2\ud83c\uddf3\ud83c\uddf4\ud83c\uddf5\ud83c\uddf6\ud83c\uddf7\ud83c\uddf8\ud83c\uddf9\ud83c\uddfa\ud83c\uddfb\ud83c\uddfc\ud83c\uddfd\ud83c\uddfe\ud83c\uddff\";\n    \/\/digits = \"\ud83c\uddeb\ud83c\uddee\ud83c\uddf8\ud83c\uddea\ud83c\uddf3\ud83c\uddf4\ud83c\udde9\ud83c\uddf0\ud83c\uddea\ud83c\uddea\ud83c\uddf1\ud83c\uddfb\ud83c\uddf1\ud83c\uddf9\";\n    \n  }\t\t       \n\n#define aDEBUG76\n#ifdef DEBUG76\n\n  if(flagidflags) {\n    int first = 1;\n    for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n      if(flagids&#91;c] == 1) {\n\tif(first) {\n\t  fprintf(stdout,\"flags: \");\n\t  first = 0;\n\t}\n\tfprintf(stdout,\" %s\",idsflags&#91;c].id);\n      }\n    }\n    if(!first)\n      fprintf(stdout,\"\\n\");\n  }\n\n#endif\n\n#ifdef DEBUG59\n\n  if(utf8) {\n\n    int xlines;\n    printcolumns(6, 0x10, 0, 64, &amp;xlines);\n    \n    int utf8output = 0;\n    for(c = 0; c &lt; 65535 * 4; c++) {\n      \/\/for(c = 0x2800; c &lt; 0x2900; c++) { \/\/ braille\n      unsigned char buffer10&#91;10];\n      if(c % 64 == 0) {\n\tif(c > 0) {\n\t  fprintf(stdout,\"\\n\");\n\t  utf8output = 0;\n\t}\n\tfprintf(stdout,\"%5x \", c);\n\tutf8output = 1; \n      }\n      if(c >= 0 &amp;&amp; c &lt; 32) {\n\tc += 31;\n\tfprintf(stdout, \"%-32s\", \"--- control characters ---\");\n\tutf8output = 1;\n      } else if(c >= 128 &amp;&amp; c &lt; 256) {\n\tc += 31;\n\tfprintf(stdout, \"%-32s\", \"--- utf8 characters ---\");\n\tutf8output = 1;\n      } else {\n\tcodetoutf8(buffer10, c);\n\tfprintf(stdout,\"%s\", buffer10);\n\tutf8output = 1;\n      }\n    }\n    if(utf8output)\n      fprintf(stdout,\"\\n\");\n    fflush(stdout);\n\n    return(0);\n  }\n\n#endif\n  \n#define aDEBUG60 2\n\n#ifdef DEBUG60\n    int xlines;\n    printcolumns(0, 2, 0, 64, &amp;xlines);\n    printcolumns(0, 8, 0, 64, &amp;xlines);\n    for(c=1;;c*=10) {\n      fprintf(stdout,\"c:%d\\n\",c);\n      printcolumns(0, 10, 0, c, &amp;xlines);\n    }\n    printcolumns(0, 16, 0, 64, &amp;xlines);\n#endif\n\n  if(size == 0)\n    size = 1;\n  else if(size > 1024)\n    size = 1024;\n  if(lines &lt; 1)\n    lines = 1;\n\n#ifdef USE_TIMER\n  timerstart = getseconds();\n#endif\n\n  if(flagdigits) \/\/ semicolon separated (flags)\n    digitscount = utf8strings(digits);\n  else \/\/ not\n    digitscount = utf8characters(digits);\n\n  \/\/digitscount = utf8characters(digits);\n  \n  if(flagdigits) \/\/ semicolon separated (flags)\n    characterlengths = utf8stringlengths(digits);\n  else\n    characterlengths = utf8lengths(digits);\n\n  \/\/characterlengths = utf8lengths(digits);\n\n#ifdef FORT\n  if(input == INPUT_FORT ||\n     input == INPUT_FORTXOR ) {\n    strcpy(fort_random_file, \"newressufort.rnd\");\n    strcpy(fort_secret_file, \"newressufortsecret.rnd\");\n    \/\/fort_verbose = 0;\n    fort_init();\n  }\n#endif\n\n  if(input == INPUT_STREAM) {\n    if(key == NULL)\n      key = stream_default_key;\n\n    stream_open(0, key);\n\n  } else if(key != NULL) {\n    fprintf(stderr,\"%s: cannot --key without --stream\\n\", procname);\n    exit(2);\n\n  }\n\n  if(fixedclock &amp;&amp; !copyreverse) {\n    fprintf(stderr,\"%s: cannot --fixedclock without --copyreverse\\n\", procname);\n    exit(2);\n\n  }\n  if(dieharder &amp;&amp; !sample) {\n    fprintf(stderr,\"%s: cannot --dieharder without --sample\\n\", procname);\n    exit(2);\n  }\n\n  if(purge_set &amp;&amp; (!dieharder || !sample)) {\n    fprintf(stderr,\"%s: cannot --purge or --save without --sample and --dieharder\\n\", procname);\n    exit(2);\n  }\n\n  if((filesize_set || blocksize_set || blocks_set) &amp;&amp; !sample) {\n    fprintf(stderr,\"%s: cannot --filesize, --blocks or --blocksize without --sample\\n\", procname);\n    exit(2);\n  }\n\n  if(input == INPUT_TEST) {\n    fprintf(stderr,\"%s: randomness from your generator (test_bytes)\\n\", procname);\n  }\n\n  if(sample) { \/\/ &amp; dieharder\n    dump_sample();\n    exit(status);\n  } \/\/ if(sample)\n\n#ifdef DEBUG19\n\n  if(flagint) {\n    unsigned char savepath&#91;128];\n\n    save_path(sizeof(savepath), savepath);\n\n    if(!strncmp(procname, \"\/bin\/newressu\", 13) &amp;&amp; exists_path(\"\/var\/ressu\"))\n      set_path(\"\/var\/ressu\");\n    else if(!strncmp(procname, \".\/newressu\", 10) &amp;&amp; exists_path(\".ressu\"))\n      set_path(\".ressu\");\n    else if(exists_path(\"\/var\/ressu\"))\n      set_path(\"\/var\/ressu\");\n    else if(exists_path(\"\/var\/newressu\"))\n      set_path(\"\/var\/newressu\");\n    else if(exists_path(\".ressu\"))\n      set_path(\".ressu\");\n    else\n      set_path(\".\/\");\n\n    unsigned char command&#91;160], date&#91;16], filename&#91;64];\n    command_readline(\"date +%Y%m%d%H\", sizeof(date), date);\n    \/\/command_readline(\"date +%Y%m%d%H%M\", sizeof(date), date);\n\n    sprintf(filename,\"newressutest14.rnd.%s\", date);\n    sprintf(command,\".\/newressutest14.sh >%s\",filename);\n    \/\/fprintf(stdout,\"date:%s, filename:%s\\n\", date, filename);\n\n    if(!exists_path(filename)) {\n      int error;\n      if((error = system(command)) != 0) {\n\tfprintf(stderr,\"%s: system(): cannot execute command '%s'\\n\", procname, command);\n      }\n    }\n    \/\/fprintf(stderr,\" done.\\n\");\n    fflush(stderr);\n\n    set_path(savepath);\n  } \/\/ if(flagint\n\n#endif\n  \n  \/\/ print used digits\n  \n  if(flagprintdigits) {\n    int count = 0;\n    unsigned char *p;\n\n    fprintf(stdout,\"digits:\");\n    \n    p = digits;\n    while(*p != '\\0') {\n      if(*p &lt; 0x80 || \/\/ ascii char\n\t *p > 0xbf) { \/\/ first utf8 byte\n\tcount++;\n#ifdef KOK\n\tif((charwidth == 2 &amp;&amp; count >= 32) ||\n\t   (charwidth == 1 &amp;&amp; count >= 72) )\n\t  break;\n#endif\n      }\n      fprintf(stdout,\"%c\", *p);\n      p++;\n    }\n    if(*p != '\\0')\n      fprintf(stdout,\"...\");\n    fprintf(stdout,\"\\n\");\n  }\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 = utf8characters(wordbuf);\n  }\n\n  pchars = 0;\n  pwords = 0;\n\n  \/\/ in beginning of line, count printed line number\n      \n  if(!quiet &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*llu\", plinesdigits, plines);\n    pchars += strlen(linenobuf);\n    pchars++;\n  }\n\n  \/\/ count words\n\n  cwords = 0;\n  \n  while((chars > 0 &amp;&amp; pchars + size * charwidth + calc_spaces(pwords) &lt;= chars) ||\n\t(words > 0 &amp;&amp; pwords &lt; words)) {\n    \n    pchars += calc_spaces();\n    pchars += (size * charwidth);\n    pwords++;\n    cwords++;\n  }\n\n  \/\/ there has to be atleast one data word\n  \n  if(pwords &lt; 1) {\n    pchars += calc_spaces();\n    pchars += (size * charwidth);\n    pwords = 1;\n  }\n\n  unsigned long wordvalues = 1, wordvaluesold;\n\n  for(c = 0; c &lt; size; c++) {\n    wordvaluesold = wordvalues;\n    wordvalues *= digitscount;\n    if(wordvalues \/ digitscount != wordvaluesold) {\n      wordvalues = 0;\n      break;\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      exit(2);\n    }\n  } else {\n    if(sort == 1 &amp;&amp; size > 0 &amp;&amp; wordvalues > 0 &amp;&amp; wordvalues &lt; pwords) {\n      fprintf(stderr, \"%s:\", procname);\n      fprintf(stderr, \" digits is less than calculated words\");\n      fprintf(stderr, \", digits:%d(%lu)\", digitscount, wordvalues);\n      fprintf(stderr, \", words:%d\\n\", pwords);\n\n      exit(2);\n    }\n  }\n\n  \/\/ \"small\" words as single newressu_gen_limit() call\n  \n  if(limit == 0 &amp;&amp; wordvalues > 0)\n    limit = wordvalues;\n\n  if(columns) {\n    int xlines;\n    printcolumns(0, 10, 0, pchars, &amp;xlines);\n    lines -= xlines;\n    if(lines &lt; 1)\n      lines = 1;\n  }\n  \n#ifdef TEST\n  if(flagint &amp;&amp; base != -1) {\n    fprintf(stderr,\"Last word: \");\n    fprintfbase(stderr, limit - 1, base);\n    fprintf(stderr,\"\\n\");\n  }\n#endif\n\n  if(stats) {\n    fprintf(stderr, \"randomsource:%s\", input_str);\n    fprintf(stderr, \", fixedclock:%d\", fixedclock);\n    if(fixedclock == 1)\n      fprintf(stderr, \", fixedclockchainlength:%d\", fixedclockchainlength);\n    fprintf(stderr, \", copyreverse:%d\", copyreverse);\n    fprintf(stderr, \", size:%d\", size);\n    fprintf(stderr, \", lines:%llu\", lines);\n    fprintf(stderr, \", pchars:%d\", pchars);\n    fprintf(stderr, \", pwords:%d\", pwords);\n    fprintf(stderr, \", sspace:%d\", sspace);\n    fprintf(stderr, \", tchars:%llu\", (unsigned long long)size * pwords * lines);\n    fprintf(stderr, \", digitscount:%d\", digitscount);\n    fprintf(stderr, \", characterlengths:%d\", characterlengths);\n    fprintf(stderr, \", strlen(digits):%ld\", strlen(digits));\n    if(wordvalues > 0)\n      fprintf(stderr, \", wordvalues:%lu\", wordvalues);\n    if(limit > 0) {\n      fprintf(stderr, \", limit:%lu\", limit);\n#ifdef DEBUG51\n      fprintf(stderr, \", type:%d\", type);\n      fprintf(stderr, \", limitsize%d:%d\", type, limitsize);\n#endif\n    }\n    fprintf(stderr, \", pid:%d\", getpid());\n    fprintf(stderr, \"\\n\");\n  }\n\n  if(help) {\n    struct helpline {\n      char *command;\n      char *text;\n    } helplines&#91;] = {\n      { \"newressu --help\/-?\", \"this help page\" },\n      { \"newressu -d\/--dec\", \"print random decimal digits (default)\" },\n      { \"newressu -o\/--oct\", \"octal digits\" },\n      { \"newressu -x\/--hex\", \"hexadecimal digits\" },\n      { \"newressu -b\/--bin\", \"binary digits\" },\n      { \"newressu -d --space\", \"decimal digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -b --space\", \"binary digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -d -l30\", \"decimal digits, 30 lines\" },\n      { \"newressu -d -l30 --lineno\", \"decimal digits, 30 lines, no linenumbers\"  },\n      { \"newressu --base2\", \"base 2 digits =decimal (0-1)\" },\n      { \"newressu --base8\", \"base 8 digits =octal (0-7)\" },\n      { \"newressu --base10\", \"base 10 digits =decimal (0-9)\" },\n      { \"newressu --base16\", \"base 16 digits =hexadecimal (0-F)\" },\n      { \"newressu --base62\", \"base 62 digits (0-9, A-Z, a-z)\" },\n      { \"newressu --rand\", \"numbers in rand style listing\"  },\n      { \"newressu --space 2\", \"numbers in 2 number groups\"  },\n      { \"newressu --newline 5\", \"print numbers in 5 line groups\"  },\n      { \"newressu -l*\", \"fill all screen lines\"  },\n      { \"newressu -c*\", \"fill all screen columns\"  },\n      { \"newressu --screen\", \"fill screen columns and lines\"  },\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 --isupper --limBAAAAA\",\"print five letter uppercase words\" },\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 --alnum\", \"alphanumeric characters\" },\n      { \"newressu --alpha\", \"alphabetic characters\" },\n      { \"newressu --graph\", \"printables excluding space\" },\n      { \"newressu --lower\", \"lowercase characters\" },\n      { \"newressu --punct\", \"punctuation characters\" },\n      { \"newressu --upper\", \"uppercase characters\" },\n      { \"newressu -1\", \"material for passwords\" },\n      { \"newressu --dnk\/--nor\", \"danish\/norwegian alphabet\" },\n      { \"newressu --fin\/--swe\", \"finnish\/norwegian alphabet\" },\n      { \"newressu --rus\", \"russian alphabet\" },\n      { \"newressu --est\", \"estonian alphabet\" },\n      { \"newressu --ltu\", \"lithuanian alphabet\" },\n      { \"newressu --lva\", \"latvian alphabet\" },\n      { \"newressu --fra\/--gbr\/--usa\/--ita\", \"french\/gb\/us\/italian alphabet\" },\n      { \"newressu --deu\", \"deutsch alphabet\" }, \n      { \"newressu --grc\", \"greek alphabet\" }, \n      { \"newressu --jp\", \"japan alphabet (hiragana, katakana, kanji) \" }, \n      { \"newressu --jp1\/--hir\", \"japan alphabet (hiragana) \" }, \n      { \"newressu --jp2\/--kat\", \"japan alphabet (katakana) \" }, \n      { \"newressu --jp3\/--kan\", \"japan alphabet (kanji) \" }, \n      { \"newressu --cn\", \"chinese alphabet\" }, \n      { \"newressu --heb\", \"hebrew alphabet\" }, \n      { \"newressu --hin\/--ind\", \"hindi alphabet\" }, \n      { \"newressu --kor\", \"korean alphabet\" }, \n      { \"newressu --got\", \"gothic alphabet\" }, \n      { \"newressu --otp5n\/--otp1\", \"\\\"one time pad\\\" (otp) with 5 numeric characters\" }, \n      { \"newressu --otp5a\/--otp2\", \"otp with 5 uppercase letters\" }, \n      { \"newressu --otp4a\/--otp3\", \"otp with 4 uppercase letters\" }, \n      { \"newressu --cards\", \"playing cards\" }, \n      { \"newressu --cardsuits\", \"playing card suits\" }, \n      { \"newressu --chessmen\", \"chess men\" }, \n      { \"newressu --dice\", \"print dice\" },\n      { \"newressu --mahjong\", \"print mahjong pieces\" },\n      { \"newressu -i\u258c\u2599\u2584 \/ --pattern1\", \"print pattern1\" },\n      { \"newressu -i\u25dc\u25dd\u25de\u25df \/ --pattern2\", \"print pattern2\" },\n      { \"newressu -i\\\\\\\\\/ \/ --pattern3\", \"print pattern2\" },\n      { \"newressu -i\u25a7\u25a8 \/ --pattern5\", \"print pattern2\" },\n      { \"newressu --ressu\", \"use randomness from ressu (default)\" },\n      { \"newressu --pseudoressu\", \"use randomness from pseudo random ressu\" },\n      { \"newressu --fast\/--fastressu\", \"use randomness from fast ressu\" },\n      { \"newressu --single\/--singleressu\", \"use randomness from single round of ressu\" },\n#ifdef FORT\n      { \"newressu --fort\", \"use randomness from fort\" },\n#endif\n#ifdef USE_RDRAND\n      { \"newressu --rdrand\", \"use randomness from intel rdrand\" },\n#endif\n#ifdef USE_RDSEED\n      { \"newressu --rdseed\", \"use randomness from intel rdseed\" },\n#endif\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(stdout, \"%-50s\", helplines&#91;c].text);\n      fprintf(stdout, \"%-25s\", helplines&#91;c].command);\n      fprintf(stdout, \"\\n\");\n    }\n\n#define DEBUG77 2\n\n#ifdef DEBUG77\n\n    unsigned char *areaflags = \"FINLAND, DENMARK, NORDIC, BALTIC, FRANCE, UK, SPAIN, EU, NORTHERNEUROPE, EASTERNEUROPE, SOUTHERNEUROPE, WESTERNEUROPE, EUROPE, EURASIA, NORTHASIA, EASTASIA, CENTRALASIA, SOUTHASIA, WESTASIA, ASIA, NORTHAFRICA, EASTAFRICA, CENTRALAFRICA, SOUTHAFRICA, WESTAFRICA, AFRICA, NORTHAMERICA, SOUTHAMERICA, USA, OCEANIA, AUSTRALASIA, MELANESIA, MICRONESIA, POLYNESIA, BRICS, ALL\", *a;\n    unsigned char name&#91;128];\n    \n    a = areaflags;\n    while(*a != '\\0' &amp;&amp; newressu_getname(sizeof(name), name, &amp;a)) {\n      fprintf(stdout,\"area:%s\",name);\n      int count = 0;\n      for(c = 0; c &lt; sizeof(idsflags) \/ sizeof(idsflags&#91;0]); c++) {\n\tif(!strcmp(name, \"ALL\")) {\n\t  count++;\n\t  unsigned char *q = idsflags&#91;c].flags;\n\t  unsigned char name2&#91;128], name3&#91;128];\n\t  newressu_getname(sizeof(name2), name2, &amp;q); \/\/ flag\n\t  newressu_getname(sizeof(name2), name2, &amp;q); \/\/ 2 char isocode\n\t  newressu_getname(sizeof(name3), name3, &amp;q); \/\/ 3 char isocode\n\t  newressu_getname(sizeof(name3), name3, &amp;q); \/\/ name\n\t  fprintf(stdout,\", %s(%s)\",name3, name2); \/\/ name and isocode2 needed\n\t} else {\t\n\t  \n\t  if(newressu_strstr(idsflags&#91;c].flags, name) != NULL) {\n\t    count++;\n\t    unsigned char *q = idsflags&#91;c].flags;\n\t    unsigned char name2&#91;128], name3&#91;128];\n\t    newressu_getname(sizeof(name2), name2, &amp;q); \/\/ flag\n\t    newressu_getname(sizeof(name2), name2, &amp;q); \/\/ 2 char isocode\n\t    newressu_getname(sizeof(name3), name3, &amp;q); \/\/ 3 char isocode\n\t    newressu_getname(sizeof(name3), name3, &amp;q); \/\/ name\n\t    fprintf(stdout,\", %s(%s)\", name3, name2); \/\/ name and isocode2 needed\n\t  }\n\t}\n      }\n      fprintf(stdout,\", count:%d\",count);\n      fprintf(stdout,\"\\n\");\n    }\n#endif\n\n    for(c = 0; c &lt; chars; c++)\n      fprintf(stdout, \"*\");\n    fprintf(stdout, \"\\n\");\n    \n    if(lines > 1)\n      lines = 1; \/\/ print one line below help as a sample\n  }\n\n  if(lines == 0)\n    exit(status);\n\n#define aDEBUG78 2\n    \n#ifdef DEBUG78\n\n    for(c = 0; c &lt; sizeof(flagchars) \/ sizeof(flagchars&#91;0]); c++) {\n      int first = 1;\n      for(d = 0; d &lt; sizeof(flagchars) \/ sizeof(flagchars&#91;0]); d++) {\n\tchar buffer&#91;32];\n\tbuffer&#91;0] = '\\0';\n\tif(!first)\n\t  strcat(buffer,\" \");\n\tstrcat(buffer, flagchars&#91;c]);\n\tstrcat(buffer, flagchars&#91;d]);\n\tfprintf(stdout,\"%s\",buffer);\n\tfirst = 0;\n      }\n      fprintf(stdout,\"\\n\");\n    }\n#endif\n  \n  int linecnt = 0;\n  unsigned char *line = NULL;\n  unsigned char wordbuf&#91;1025];\n  \n  for(;;) {\n\n    if(!sort) { \/\/ no sort, no lotto\n\n      for(cwords = 0; cwords &lt; pwords; cwords++) {\n\treadword(wordbuf);\n\n\tif(!quiet) {\n\n\t  \/\/ in beginning of line, print line number\n\n\t  print_line_number();\n\t\n\t  \/\/ want to print spaces between \"words\"?\n\n\t  print_spaces(' ');\n\t\n\t  \/\/ print word\n\n\t  print_word(wordbuf);\n\n\t  newressu_output = 1;\n\t}\n\n      } \/\/ for(cwords = 0; cwords &lt; pwords; cwords++) {\n    } else { \/\/ if(!sort)\n\n      line_clear(&amp;linecnt, &amp;line);\n\n      \/\/ fetch and save words on this row\n\n      for(cwords = 0; cwords &lt; pwords; \/*!*\/) {\n\treadword(wordbuf);\n\n\tif(line_add_string_sort(&amp;linecnt, &amp;line, wordbuf)) {\n\t  cwords++; \/\/ added if unique\n\t}\n      } \/\/ while(cwords &lt; pwords) {\n\n      \/\/ print words on this row\n\n      for(cwords = 0; cwords &lt; pwords; cwords++) {\n\n\tline_get_string(sizeof(wordbuf), wordbuf, cwords, line);\n\n\tif(!quiet) {\n\n\t  \/\/ in beginning of line, print line number\n\n\t  print_line_number();\n\t\n\t  \/\/ want to print spaces between \"words\"?\n\t\n\t  print_spaces(' ');\n\n\t  \/\/ print word\n\t\n\t  print_word(wordbuf);\n\n\t  newressu_output = 1;\n\t}\n      } \/\/ end of for(cwords = 0; cwords &lt; pwords; cwords++\n    } \/\/ if(!sort)\n\n    if(!quiet) {\n      fprintf(stdout, \"\\n\");\n    }\n\n    plines++;\n    ptotallines++;\n\n    \/\/ print empty line\n\n    if(!quiet &amp;&amp;\n       snewline > 0 &amp;&amp;\n       plines%snewline == 0) {\n      \/\/ if screenfull printed, use\n      \/\/ total lines (contains also\n      \/\/ empty lines), if not\n      \/\/ screenfull use printed\n      \/\/ lines (without empty lines)\n      if((screen &amp;&amp; ptotallines &lt; lines) ||\n\t (!screen &amp;&amp; plines &lt; lines)) {\n\tfprintf(stdout, \"\\n\");\n\tptotallines++;\n      }\n    }\n\n    \/\/fflush(stdout);\n    \n    newressu_output = 0;\n    \n    \/\/ all needed lines printed?\n\n    if(screen &amp;&amp; snewline > 0 &amp;&amp;\n       ptotallines >= lines)\n      break;\n    if(plines >= lines)\n      break;\n\n#define STATDIV (1024 * 1024 * 100)\n    \n    if(print_statline) {\n      if(isatty(STDOUT_FILENO)) { \/\/ 0=stdin, 1=stdout, 2=stderr\n\tprint_statline = 0;\n      } else {\n\tif(lines % 1000 == 0) {\n\t  unsigned char buf10&#91;10];\n\t  unsigned long long bytes;\n\t  int pros = (int)(((double)plines \/ lines) * 100);\n\n\t  bytes = (((unsigned long long)size * pwords * plines) \/ STATDIV) * STATDIV;\n\t  stat_line_get_readable(buf10, bytes);\n\t  \n#ifdef DEBUG97\n\t  fprintf(stderr, \"%lld\", (unsigned long long)size * pwords * plines);\n\t  fprintf(stderr, \", %lld\", bytes);\n\t  fprintf(stderr, \", %s\", buf10);\n\t  fprintf(stderr, \"\\n\");\n#endif\n\t  stat_line_begin();\n\t  stat_line_printf(\"%s characters written:\", input_str);\n\t  stat_line_readable((unsigned long) size * pwords * plines);\n\t  stat_line_printf(\", %d%%\", pros);\n\t  \/\/stat_line_printf(\", lines:%lld\",lines);\n\t  \/\/stat_line_printf(\", plines:%lld\",plines);\n\t  stat_line_end();\n\t}\n\tstat_line_cursor();\n      }\n    } \/\/ if(print_statline)\n  } \/\/ for(;;)\n\n  if(print_statline) { \/\/ 0=stdin, 1=stdout, 2=stderr\n    stat_line_begin();\n    stat_line_end();\n    stat_line_cursor_remove();\n  }\n\n#ifdef DEBUG2H\n\n  int itemlen = 0;\n  for(int c = 0; c &lt; ressuct_bytes; c++) {\n    unsigned char buffer&#91;16];\n    sprintf(buffer, \"%lu\", count&#91;c]);\n    if(itemlen &lt; strlen(buffer))\n      itemlen = strlen(buffer);\n  }\n  for(int c = 0; c &lt; ressuct_bytes; c++) {\n    if(c % 16 == 0) {\n      if(c > 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%05u \", c);\n    }\n    fprintf(stdout,\"%*lu\", itemlen + 1, count&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n\n#endif\n  \n#ifdef USE_TIMER\n\n  if(timer) {\n    double timertook = getseconds() - timerstart;\n    fprintf(stderr, \"%s run time %f seconds\", input_str, timertook);\n    fprintf(stderr, \", %lld lines\", plines);\n    fprintf(stderr, \", %f useconds\/line\", timertook * 1000000 \/ plines);\n    fprintf(stderr, \", %d characters\/line\", pwords * size);\n    fprintf(stderr, \", %f useconds\/character\",\n\t    (timertook * 1000000 \/ plines) \/ (pwords * size) );\n    fprintf(stderr, \"\\n\");\n  }\n\n#endif\n\n  fflush(stdout);\n\n  if(digitsext != NULL)\n    free(digitsext);\n  \n#ifdef FORT\n\n  if(input == INPUT_FORT ||\n    input == INPUT_FORTXOR) {\n    fort_save();\n  }\n\n#endif\n  newressu_clear();\n  \n  exit(status);\n}\n\n#endif \/\/ MAIN<\/code><\/pre>\n\n\n\n<p>newressutest14.sh<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/bin\/newressu --int --single --space2 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space3 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space4 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space5 --newline 5 -l1 $@\n\/bin\/newressu --int --single --space6 --newline 5 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s1 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s2 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s3 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s4 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s5 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s6 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s7 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s8 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s9 -l1 $@\n\/bin\/newressu --int --single --6bits --space -s10 -l1 $@\n\/bin\/newressu --int --single --rand -l1 $@\n\/bin\/newressu --int --single --alnum -l1 $@\n\/bin\/newressu --int --single --alpha -l1 $@\n\/bin\/newressu --int --single --graph -l1 $@\n\/bin\/newressu --int --single --lower -l1 $@\n\/bin\/newressu --int --single --punct -l1 $@\n\/bin\/newressu --int --single --upper -l1 $@\n\/bin\/newressu --int --single -d --lim41 -w7 --zero -l1 --lotto$@\n\/bin\/newressu --int --single --1bit -l1 $@\n\/bin\/newressu --int --single --2bits -l1 $@\n\/bin\/newressu --int --single --3bits -l1 $@\n\/bin\/newressu --int --single --oct -l1 $@\n\/bin\/newressu --int --single --4bits -l1 $@\n\/bin\/newressu --int --single --hex -l1 $@\n\/bin\/newressu --int --single --HEX -l1 $@\n\/bin\/newressu --int --single --5bits -l1 $@\n\/bin\/newressu --int --single --6bits -l1 $@\n\/bin\/newressu --int --single --dnk -l1 $@\n\/bin\/newressu --int --single --nor -l1 $@\n\/bin\/newressu --int --single --fin -l1 $@\n\/bin\/newressu --int --single --swe -l1 $@\n\/bin\/newressu --int --single --rus -l1 $@\n\/bin\/newressu --int --single --est -l1 $@\n\/bin\/newressu --int --single --ltu -l1 $@\n\/bin\/newressu --int --single --lva -l1 $@\n\/bin\/newressu --int --single --fra -l1 $@\n\/bin\/newressu --int --single --gbr -l1 $@\n\/bin\/newressu --int --single --usa -l1 $@\n\/bin\/newressu --int --single --ita -l1 $@\n\/bin\/newressu --int --single --eng -l1 $@\n\/bin\/newressu --int --single --deu -l1 $@\n\/bin\/newressu --int --single --grc -l1 $@\n\/bin\/newressu --int --single --jp -l1 $@\n\/bin\/newressu --int --single --jp1 -l1 $@\n\/bin\/newressu --int --single --hir -l1 $@\n\/bin\/newressu --int --single --jp2 -l1 $@\n\/bin\/newressu --int --single --kat -l1 $@\n\/bin\/newressu --int --single --jp3 -l1 $@\n\/bin\/newressu --int --single --cn -l1 $@\n\/bin\/newressu --int --single --kan -l1 $@\n\/bin\/newressu --int --single --kor -l1 $@\n\/bin\/newressu --int --single --ind -l1 $@\n\/bin\/newressu --int --single --hin -l1 $@\n\/bin\/newressu --int --single --som -l1 $@\n\/bin\/newressu --int --single --SOM -l1 $@\n\/bin\/newressu --int --single --SO -l1 $@\n\/bin\/newressu --int --single --braille -l1 $@\n\/bin\/newressu --int --single --dna -l1 $@\n\/bin\/newressu --int --single --DNA -l1 $@<\/code><\/pre>\n\n\n\n<p>newressu.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes(int size, unsigned char *buffer);\nunsigned long ressu_gen_limit(unsigned long limit);\nvoid pseudoressu_bytes(int buflen, unsigned char *buf);\nvoid inccvar();\nvoid clearcvar();\n\n#define INPUT_RESSU 0\n#define INPUT_PSEUDORESSU 1\n#define INPUT_FASTRESSU 3\n#define INPUT_SINGLERESSU 4\n#define INPUT_FIXED 5\n\n#define INPUT_STREAM 10\n#define INPUT_FORT 11\n#define INPUT_FORTXOR 12\n#define INPUT_RDRAND 13\n#define INPUT_RDSEED 14\n#define INPUT_URANDOM 15\n#define INPUT_RANDOM 16\n#define INPUT_DUMMY 17\n\nextern int verbose;\n\nextern int input;\nextern int newressu_output;\nextern char *randomgen&#91;];\nextern void pseudoressu_bytes(int, unsigned char *);<\/code><\/pre>\n\n\n\n<p>fort.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;time.h&gt;\n#include &lt;ctype.h&gt;\n\n#include &lt;sys\/time.h&gt;\n#include &lt;errno.h&gt;\n\n#include &lt;openssl\/ssl.h&gt;\n\n#include \"sha256.h\"\n#include \"newressu.h\"\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"fort version 0.52 \u00a9\";\nunsigned char *fortuseragent = \"fort version 0.52 \u00a9\"; \nstatic unsigned char *copyright = \"Copyright (c) 2020-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FORT_INTERNAL_EVENTS 2\n\n#define aDEBUG10 2\n#define aDEBUG18 2\n\n#define FORT_XOR_VERSION 2\n#define FORT_ORIGINAL_VERSION 2\n\n#include \"fort.h\"\n\nint fort_events = 1;\nint fort_use_web = 0;\n\n#define DEBUG 2\n#define FORT_MIN_POOL_SIZE 64\nstatic unsigned int fort_internal_events = 1;\nstatic unsigned int fort_internal_event_mode = 1;\n\n#define FORT_USE_WEB 2\n#define FORT_USE_URANDOM 2\n#define aFORT_USE_RANDOM 2\n#define FORT_USE_NEWRESSU_COMMAND 2\n\nunsigned char fort_random_file&#91;128] = \"fort.rnd\";\n\n#ifdef DEBUG10\nstatic int event_id = 0;\nstatic char fort_events_file&#91;128] = \"fortevents.deb\";\n#endif\n\n\/\/ Additional secrets to fort\n\/\/ (Adversary must guess these too)\n\n#define ADDITIONAL_SECRETS 2\n#ifdef ADDITIONAL_SECRETS\nunsigned char fort_secret_file&#91;128] = \"fortsecret.rnd\";\nunsigned char *program_secret = \"OHUwiVmwm8HlqNhKxPi9rdt_8lm4jXI8hi-FCntPAQN_UXOyt4s6zQnRo__ySAd1\";  \n#endif\n\n#define FORT_64_POOLS 2\n\n#ifdef FORT_64_POOLS\n#define FORT_POOLS 64\ntypedef unsigned long FORT_COUNTER;\n#else\n#define FORT_POOLS 32\ntypedef unsigned int FORT_COUNTER;\n#endif\n\nvoid fort_mix();\n\nvoid hash_update_cvar(HashCtx *hash)\n{\n  hash_update(hash, (unsigned char *)&amp;cvar,\n\t      cvarsize + 1);\n\n  inccvar();  \n}\n\n#define aDEBUG8 2\n\nvoid hash_update_ressu(HashCtx *hash)\n{\n  unsigned char temp&#91;16];\n  ressu_genbytes(sizeof(temp), temp);\n\n#ifdef DEBUG8\n  fprintf(stdout,\", ressu:\");\n  for(int c = 0; c &lt; sizeof(temp); c++)\n    fprintf(stdout,\"%02x\", temp&#91;c]);\n#endif\n  \n  hash_update(hash, temp, sizeof(temp));\n}    \n\nstatic IUTIME gettenths()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec * 10 +\n      (int)tv.tv_usec \/ 100000);\n}\n\nstatic IUTIME getmicroseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec * 1000000 +\n      tv.tv_usec);\n}\n\nstatic IUTIME getseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec);\n}\n\nstruct fort_pool {\n  unsigned long length;\n  HashCtx pool;\n};\n\nstatic struct fort_pool fort_pools&#91;FORT_POOLS];\n\nvoid fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf)\n{\n  while(len &gt; 1 &amp;&amp; buf&#91;len-1] == 0)\n    len--;\n\n  HashUpdate(&amp;fort_pools&#91;*pool].pool, buf, len);\n  fort_pools&#91;*pool].length += len; \/\/ (unsigned long)2097152*16384;\n\n#ifdef DEBUG10\n  if(event_id &lt; 65536) {\n    FILE *fp1;\n    if((fp1 = fopen(fort_events_file, \"a\")) != NULL) {\n      fprintf(fp1,\"id=%d\", event_id);\n      fprintf(fp1,\", source=%02d\", source);\n      fprintf(fp1,\", pool=%02d\", *pool);\n      fprintf(fp1,\", mode=%d\", mode);\n      fprintf(fp1,\", len=%d\", len);\n      fprintf(fp1,\", data=\");\n      for(int c=0;c&lt;len;c++)\n        fprintf(fp1,\"%02x\", buf&#91;c]);\n      fprintf(fp1,\"\\n\");\n      fflush(fp1);\n      fclose(fp1);\n      event_id++;\n    }\n  }\n#endif\n\n  switch(mode) {\n\n  case 1:\n    (*pool) = ((*pool) + 1) % FORT_POOLS;\n    break;\n\n  case 3:\n    break; \/\/ caller decides next pool\n\n  }\n}\n\nvoid fort_add_random_event_timer_start(IUTIME *micros)\n{\n  *micros = getmicroseconds();\n}\n\nvoid fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *micros)\n{\n  unsigned char temp&#91;2];\n  IUTIME t;\n\n  t = getmicroseconds() - *micros;\n  temp&#91;0] = t &amp; 0xff;\n  temp&#91;1] = (t &gt;&gt; 8) &amp; 0xff;\n\n  fort_add_random_event(pool, source, mode,\n\t\t\tsizeof(temp), temp);\n}\n\nvoid fort_add_random_event_time(int *pool, int source, int mode)\n{\n  int len;\n  unsigned char temp&#91;2];\n  IUTIME t;\n  static int prev_second = -1;\n\n  t = getmicroseconds();\n  temp&#91;0] = t &amp; 0xff;\n  temp&#91;1] = (t &gt;&gt; 8) &amp; 0xff;\n  len = 2;\n\n  if(prev_second == temp&#91;1]) {\n    len--;\n  } else {\n    prev_second = temp&#91;1];\n  }\n\n  fort_add_random_event(pool, source, mode,\n\t       len, temp);\n}\n\nvoid fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf, int size)\n{\n  int n;\n\n  while(len != 0) {\n    n = (size&lt;len)? size:len;\n    fort_add_random_event(pool, source,\n        mode, n, buf);\n    buf += n;\n    len -= n;\n  }\n}\n\n#define aDEBUG18 2\n\nvoid hash_init(HashCtx *hash)\n{\n  FORT_INTERNAL_EVENTS_START(10)\n\n  HashInit(hash);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"init\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(11)\n}\n\nvoid hash_update(HashCtx *hash, unsigned char *data, int len)\n{\n  FORT_INTERNAL_EVENTS_START(12)\n\n  HashUpdate(hash, data, len);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"update    \");\n  for(int d = 0; d &lt; len; d++)\n    fprintf(stdout,\"%02x\",data&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(13)\n}\n\nvoid hash_final(unsigned char digest&#91;HashLen], HashCtx *hash)\n{\n  FORT_INTERNAL_EVENTS_START(14)\n\n  HashFinal(digest, hash);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"final     \");\n  for(int d = 0; d &lt; HashLen; d++)\n    fprintf(stdout,\"%02x\", digest&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(15)\n}\n\nstatic unsigned char fort_key&#91;HashLen];\n\nvoid fort_rekey(unsigned char *digest)\n{\n  HashCtx hash;\n\n  FORT_INTERNAL_EVENTS_START(16)\n\n  hash_init(&amp;hash);\n  hash_update(&amp;hash, fort_key, sizeof(fort_key));\n  hash_update_cvar(&amp;hash);\n  hash_final(digest, &amp;hash);\n\n  \/\/ Forget hash\n\n  memset(&amp;hash, 0, sizeof(hash));\n\n  FORT_INTERNAL_EVENTS_END(17)\n}\n\n#define FORT_PSEUDO_LIMIT 1048576\n\n\/\/ use \n\/\/ $ .\/newressu --fort -x -w32 -s2 -l2000 --space | more\n\/\/ to debug...\n\n\/\/ choose one of\n\/\/     60 (1 minute)\n\/\/     300 (5 minutes)\n\/\/     600 (10 minutes)\n\/\/     900 (15 minutes)\n\/\/     1200 (20 minutes)\n\/\/     1800 (30 minutes)\n\/\/     3600 (hour)\n\/\/     7200 (2 hours)\n\/\/     10800 (3 hours)\n\/\/     14400 (4 hours)\n\/\/     21600 (6 hours)\n\/\/     28800 (8 hours)\n\/\/     43200 (12 hours)\n\/\/     86400 (24 hours)\n\/\/ to get readable report..\n\n#define FORT_SECONDS_BETWEEN_SAVES 10 * 60\nstatic IUTIME fort_next_save = 0;\n\n#define TIMEFORMAT \"%Z%Y%m%d%H%M%S\"\n\nvoid fort_save();\n\nstatic char current_timezone&#91;10];\n\n#define aDEBUG22 2\n\nvoid fort_reseed(int len, unsigned char *buf)\n{\n  HashCtx hash;\n\n  FORT_INTERNAL_EVENTS_START(22)\n  \n  hash_init(&amp;hash);\n  hash_update(&amp;hash, fort_key, sizeof(fort_key));\n  hash_update_cvar(&amp;hash);\n  hash_update(&amp;hash, buf, len);\n\n#ifdef DEBUG22\n  fprintf(stdout,\"\\nprevkey   \");\n  for(int d = 0; d &lt; sizeof(fort_key); d++)\n    fprintf(stdout,\"%02x\", fort_key&#91;d]);\n  fprintf(stdout,\"\\ncvar      \");\n  for(int d = 0; d &lt; cvarsize + 1; d++)\n    fprintf(stdout,\"%02x\", cvar&#91;d]);\n  fprintf(stdout,\"\\ndata      \");\n  for(int d = 0; d &lt; HashLen; d++)\n    fprintf(stdout,\"%02x\", buf&#91;d]);\n  fprintf(stdout,\"\\ndata asc  \");\n  for(int d = 0; d &lt; len; d++) {\n    if(isprint(buf&#91;d]))\n      fprintf(stdout,\"%c\", buf&#91;d]);\n    else\n      fprintf(stdout,\"\\\\%02x\", buf&#91;d]);\n  }\n#endif\n  \n  hash_final(fort_key, &amp;hash);\n\n#ifdef DEBUG22\n  fprintf(stdout,\"\\nnewkey    \");\n  for(int d = 0; d &lt; sizeof(fort_key); d++)\n    fprintf(stdout,\"%02x\", fort_key&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  memset(&amp;hash, 0, sizeof(hash));\n\n  if(fort_next_save != 0) {\n    IUTIME seconds;\n    seconds = getseconds();\n    \n    char timezone&#91;10];\n    strftime(timezone, sizeof(timezone), \"%Z\",\n             localtime((time_t *)&amp;seconds) );\n    if(strcmp(current_timezone, timezone)) {\n      fort_next_save = 1;\n      strcpy(current_timezone, timezone);\n    }\n    \n    if(fort_next_save != 0 &amp;&amp;\n       seconds &gt;= fort_next_save) {\n      \n      IUTIME diff=\n        timegm(localtime((time_t *)&amp;seconds)) - seconds;\n      \n      fort_next_save = seconds -\n        ((seconds + diff) %\n         FORT_SECONDS_BETWEEN_SAVES) +\n        FORT_SECONDS_BETWEEN_SAVES;\n      \n      fort_save();\n    }\n  }\n\n  FORT_INTERNAL_EVENTS_END(23)\n}\n\nstatic FORT_COUNTER fort_reseed_count = 0;\nstatic IUTIME fort_next_reseed = 0;\n\n#define aDEBUG28 2\n\n#ifdef FORT_ORIGINAL_VERSION\n\nvoid fort_pseudo_random_data(int len, \n    unsigned char *buf)\n{\n  unsigned char digest&#91;HashLen];\n  unsigned int n, blockbytes;\n#ifdef DEBUG28\n  int d = 0;\n#endif\n\n  FORT_INTERNAL_EVENTS_START(18)\n\n  blockbytes = 0;\n\n  while(len != 0) {\n    FORT_INTERNAL_EVENTS_START(19)\n\n    fort_rekey(digest);\n    n = (len &lt; HashLen) ? len : HashLen;\n\n#ifdef DEBUG28\n    \n    fprintf(stdout,\"\\nbuf(%02x):  \",d++);\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]);\n    fprintf(stdout,\"\\ndigest:   \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",digest&#91;c]);\n    fprintf(stdout,\"\\nsum:      \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]^digest&#91;c]);\n    fprintf(stdout,\"\\n\");\n\n#endif \/\/ #ifdef DEBUG18\n\n    memcpy(buf, digest, n);\n\n    buf += n;\n    len -= n;\n    blockbytes += n;\n\n    \/\/ rekey every 1048576 bytes if data left\n\n    if(blockbytes &gt;= FORT_PSEUDO_LIMIT &amp;&amp;\n        len &gt; 0) {                                                                                                              \n      fort_rekey(fort_key);\n      blockbytes = 0;\n    }\n\n    FORT_INTERNAL_EVENTS_END(20)\n  }\n\n  fort_rekey(fort_key);\n\n  \/\/ Forget last bytes\n\n  memset(digest, 0, sizeof(digest));\n\n  FORT_INTERNAL_EVENTS_END(21)\n}\n\n#define aDEBUG34 2\n\nvoid fort_random_data(int len, unsigned char *buf)\n{\n  int c;\n  IUTIME tenths;\n  HashCtx hash;\n  unsigned char digest&#91;HashLen];\n\n  FORT_INTERNAL_EVENTS_START(24)\n\n  tenths = gettenths();\n\n  if( (fort_next_reseed == 0) ||\n      (fort_next_reseed &lt;= tenths &amp;&amp;\n      fort_pools&#91;0].length &gt;=\n      FORT_MIN_POOL_SIZE) ) {\n\n    fort_mix();\n    \n    \/\/ next tenth of a second\n\n    fort_next_reseed = tenths + 1;\n    fort_reseed_count++;\n\n    hash_init(&amp;hash);\n    c = 0;\n\n    while(c &lt; FORT_POOLS &amp;&amp; (fort_reseed_count\n        % (1 &lt;&lt; c)) == 0) {\n\n      FORT_INTERNAL_EVENTS_START(25)\n\n      hash_final(digest, &amp;fort_pools&#91;c].pool);\n\n#ifdef DEBUG34\n      fprintf(stdout,\"\\ndata   %2d \",c);\n      for(int d = 0; d &lt; HashLen; d++)\n\tfprintf(stdout,\"%02x\",digest&#91;d]);\n#endif\n\n      hash_update(&amp;hash, digest, sizeof(digest));\n      fort_pools&#91;c].length = 0;\n      HashInit(&amp;fort_pools&#91;c].pool);\n\n      \/\/ save earlier pool to new one\n\n      hash_update(&amp;fort_pools&#91;c].pool,\n        digest, sizeof(digest));\n      c++;\n\n      FORT_INTERNAL_EVENTS_END(26)\n    }\n    hash_update_cvar(&amp;hash);\n    hash_final(digest, &amp;hash);\n\n#ifdef DEBUG34\n    fprintf(stdout,\"\\ndigest    \");\n    for(int d = 0; d &lt; HashLen; d++)\n      fprintf(stdout,\"%02x\", digest&#91;d]);\n    fprintf(stdout,\"\\n\");\n#endif\n\n    fort_reseed(sizeof(digest), digest);\n\n    \/\/ Forget hash context\n\n    memset(&amp;hash, 0, sizeof(hash));\n\n    \/\/ Forget reseed key\n\n    memset(digest, 0, sizeof(digest));\n  }\n\n  fort_pseudo_random_data(len, buf);\n\n  FORT_INTERNAL_EVENTS_END(27)\n}\n\n#endif \/\/ #ifdef FORT_ORIGINAL_VERSION\n\n#ifdef FORT_XOR_VERSION\n\nvoid fort_pseudo_random_data_xor(int len, \n    unsigned char *buf)\n{\n  unsigned char digest&#91;HashLen];\n  unsigned int n, blockbytes;\n#ifdef DEBUG28\n  int d = 0;\n#endif\n\n  FORT_INTERNAL_EVENTS_START(18)\n\n  blockbytes = 0;\n\n  while(len != 0) {\n    FORT_INTERNAL_EVENTS_START(19)\n      \n    fort_rekey(digest);\n    n = (len &lt; HashLen) ? len : HashLen;\n\n#ifdef DEBUG28\n\n    fprintf(stdout,\"\\nbuf(%02x):  \", d++);\n    for(int c = 0; c &lt; n; c++)\n      fprintf(stdout,\"%02x\", buf&#91;c]);\n    fprintf(stdout,\"\\ndigest:   \");\n    for(int c = 0; c &lt; n; c++)\n      fprintf(stdout,\"%02x\", digest&#91;c]);\n    fprintf(stdout,\"\\nsum:      \");\n    for(int c = 0; c &lt; n; c++)\n      fprintf(stdout,\"%02x\", buf&#91;c] ^ digest&#91;c]);\n    fprintf(stdout,\"\\n\");\n\n#endif\n    \n    for(int c = 0; c &lt; n; c++)\n      buf&#91;c] ^= digest&#91;c];\n\n    buf += n;\n    len -= n;\n    blockbytes += n;\n\n    \/\/ rekey every 1048576 bytes if data left\n\n    if(blockbytes &gt;= FORT_PSEUDO_LIMIT &amp;&amp;\n        len &gt; 0) {                                                                                                              \n      fort_rekey(fort_key);\n      blockbytes = 0;\n    }\n\n    FORT_INTERNAL_EVENTS_END(20)\n  }\n\n  fort_rekey(fort_key);\n\n  \/\/ Forget last bytes\n\n  memset(digest, 0, sizeof(digest));\n\n  FORT_INTERNAL_EVENTS_END(21)\n}\n\nvoid fort_random_data_xor(int len, unsigned char *buf)\n{\n  int c;\n  IUTIME tenths;\n  HashCtx hash;\n  unsigned char digest&#91;HashLen];\n\n  FORT_INTERNAL_EVENTS_START(24)\n\n  tenths = gettenths();\n\n  if( (fort_next_reseed == 0) ||\n      (fort_next_reseed &lt;= tenths &amp;&amp;\n      fort_pools&#91;0].length &gt;=\n      FORT_MIN_POOL_SIZE) ) {\n\n    fort_mix();\n\n    \/\/ next tenth of a second\n\n    fort_next_reseed = tenths + 1;\n    fort_reseed_count++;\n\n    hash_init(&amp;hash);\n    c = 0;\n\n    while(c &lt; FORT_POOLS &amp;&amp; (fort_reseed_count\n        % (1 &lt;&lt; c)) == 0) {\n\n      FORT_INTERNAL_EVENTS_START(25)\n\n      hash_final(digest, &amp;fort_pools&#91;c].pool);\n\n#ifdef DEBUG34\n      fprintf(stdout,\"\\ndata   %2d \", c);\n      for(int d = 0; d &lt; HashLen; d++)\n\tfprintf(stdout,\"%02x\", digest&#91;d]);\n#endif\n      \n      hash_update(&amp;hash, digest, sizeof(digest));\n      fort_pools&#91;c].length = 0;\n      HashInit(&amp;fort_pools&#91;c].pool);\n\n      \/\/ save earlier pool to new one\n\n      hash_update(&amp;fort_pools&#91;c].pool,\n        digest, sizeof(digest));\n      c++;\n\n      FORT_INTERNAL_EVENTS_END(26)\n    }\n    hash_update_cvar(&amp;hash);\n    hash_final(digest, &amp;hash);\n\n#ifdef DEBUG34\n    fprintf(stdout,\"\\ndigest    \");\n    for(int d = 0; d &lt; HashLen; d++)\n      fprintf(stdout,\"%02x\", digest&#91;d]);\n    fprintf(stdout,\"\\n\");\n#endif\n    \n    fort_reseed(sizeof(digest), digest);\n\n    \/\/ Forget hash context\n\n    memset(&amp;hash, 0, sizeof(hash));\n\n    \/\/ Forget reseed key\n\n    memset(digest, 0, sizeof(digest));\n  }\n\n  fort_pseudo_random_data_xor(len, buf);\n\n  FORT_INTERNAL_EVENTS_END(27)\n}\n\n#endif \/\/ #ifdef FORT_XOR_VERSION\n\n#define FORTCNT 128\n\nstatic unsigned int fort_cnt = FORTCNT;\nstatic unsigned char fort_bytes&#91;FORTCNT];\nstatic int fort_byte = 999999999;\n\nint fort_random_data_byte()\n{\n  if(fort_byte &gt;= fort_cnt) {\n    fort_random_data(fort_cnt, fort_bytes);\n    fort_byte = 0;\n  }\n  return(fort_bytes&#91;fort_byte++]);\n}\n\nvoid fort_clear()\n{\n  memset(fort_bytes, 0, fort_cnt);\n  fort_byte = 999999998;\n}\n\nint fort_random_data_byte_limit(int limit)\n{\n  int c;\n\n  while((c = fort_random_data_byte())&gt;=\n      (256 \/ limit) * limit);\n\n  return(c % limit);\n}\n\nvoid fort_random_data_buffer(int size,\n    unsigned char *buffer)\n{\n  int c;\n\n  for(c = 0; c &lt; size; c++)\n    buffer&#91;c] ^= fort_random_data_byte();\n}\n\n#define aDEBUG53 2\n\nvoid fort_reseed_file(unsigned char *filename)\n{\n  int c, cnt, bytes, characters;\n#ifdef DEBUG53\n  unsigned char *p;\n#endif\n  FILE *fp1;\n  unsigned char buffer&#91;1024], digest&#91;HashLen];\n\n  HashCtx hash;\n\n  bytes = 0;\n  characters = 0;\n  \n  if((fp1 = fopen(filename, \"r\")) != NULL) {\n    HashInit(&amp;hash);\n    while(fgets(buffer, sizeof(buffer), fp1) != NULL) {\n      cnt = strlen(buffer);\n      HashUpdate(&amp;hash, buffer, cnt);\n      bytes += cnt;\n      for(c = 0; c &lt; cnt; c++) {\n\tif(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\t  characters++;\n      }\n#ifdef DEBUG53\n      p = buffer;\n      while(*p != '\\0') {\n\tif(*p == '\\\\')\n\t  fprintf(stdout, \"\\\\\\\\\");\n\telse if(isprint(*p) || *p == '\\n')\n\t  fputc(*p, stdout);\n\telse\n\t  fprintf(stdout,\"\\\\%02x\", *p);\n\tp++;\n      }\n#endif\n    }\n    hash_update_cvar(&amp;hash);\n    HashFinal(digest, &amp;hash);\n\n    fort_reseed(sizeof(digest), digest);\n\n    fclose(fp1);\n  }\n#ifdef DEBUG53\n  \/\/if(verbose) {\n  fprintf(stdout,\"fort_reseed_file %s\", filename);\n  fprintf(stdout,\", %d bytes read\", bytes);\n  fprintf(stdout,\", %d characters read\", characters);\n  fprintf(stdout,\", sha256: \");\n  for(int c = 0; c &lt; HashLen; c++) {\n    fprintf(stdout,\"%02x\", digest&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  \/\/}\n#endif\n}\n\n#define FORT_SAVE_SIZE 1024\n\n#define aDEBUG57\n\nvoid fort_save()\n{\n  FILE *fp1;\n  unsigned char buffer&#91;FORT_SAVE_SIZE];\n\n  memset(buffer, 0, sizeof(buffer));\n\n  if((fp1 = fopen(fort_random_file, \"w\")) != NULL) {\n    fort_pseudo_random_data(sizeof(buffer), buffer);\n\n#ifdef DEBUG57\n    for(int c = 0; c &lt; sizeof(buffer); c++) {\n      if(c % 32 == 0) {\n\tif(c != 0)\n\t  fprintf(stdout,\"\\n\");\n\tfprintf(stdout,\"save      %05d \", c);\n      }\n      fprintf(stdout,\" %02x\", buffer&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n#endif\n    fwrite(buffer, 1, sizeof(buffer), fp1);\n    memset(buffer, 0, sizeof(buffer));\n    fclose(fp1);\n  }\n}\n\nvoid fort_restore()\n{\n  int d;\n#ifdef DEBUG57\n  int random;\n#endif\n  FILE *fp1;\n  unsigned char buffer&#91;FORT_SAVE_SIZE];\n\n  memset(buffer, 0, sizeof(buffer));\n  \n  if((fp1 = fopen(fort_random_file, \"r\"))\n      != NULL) {\n    d = fread(buffer, 1, sizeof(buffer), fp1);\n    fclose(fp1);\n#ifdef DEBUG57\n    random = 0;\n#endif\n  } else {\n    fort_pseudo_random_data(sizeof(buffer), buffer);\n    ressu_genbytes(sizeof(buffer), buffer);\n    d = sizeof(buffer);\n#ifdef DEBUG57\n    random = 1;\n#endif\n  }\n#ifdef DEBUG57\n  for(int c = 0; c &lt; sizeof(buffer); c++) {\n    if(c % 32 == 0) {\n      if(c != 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"restore\");\n      if(random)\n\tfprintf(stdout,\"*\");\n      else\n\tfprintf(stdout,\" \");\n      fprintf(stdout,\"  %05d \", c);\n    }\n    fprintf(stdout,\" %02x\", buffer&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n#endif\n  fort_reseed(d, buffer);\n  memset(buffer, 0, sizeof(buffer));\n\n  fort_save();\n}\n\n#if defined FORT_USE_URANDOM || \\\n    defined FORT_USE_RANDOM\n\nstatic void fort_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\n#endif\n\n#ifdef FORT_USE_WEB\n\nstatic void parse_string(unsigned char *string, int size, unsigned char **p2)\n{\n  int count;\n  unsigned char *p, *q;\n\n  p = *p2;\n  q = string;\n  count = 0;\n\n  \/\/ uppercase &amp; lowercase letters, '.'\n  \/\/ or utf-8\n\n  while(isalnum(*p) || *p == '.' || *p &gt; 0x80) {\n    if(++count &lt; size)\n      *q++ = *p;\n    p++;\n  }\n  *q = '\\0';\n  *p2 = p;\n}\n\n#endif \/\/ #ifdef FORT_USE_WEB\n\n#ifdef FORT_USE_WEB\n\nstatic int check_string(unsigned char *string, unsigned char *p)\n{\n  int ok;\n\n  ok = 0;\n  if(!strncmp(string, p, strlen(string))) {\n    ok = 1;\n  }\n\n  return(ok);\n}\n\n#endif \/\/ #ifdef FORT_USE_WEB\n\nvoid fort_internal_random_data_1(int size, char *buf)\n{\n  ressu_genbytes(size, buf);\n#ifdef FORT_XOR_VERSION\n  fort_pseudo_random_data_xor(size, buf);\n#endif\n}\n\nvoid fort_internal_random_data_2(int size, char *buf)\n{\n#ifdef FORT_XOR_VERSION\n  fort_pseudo_random_data_xor(size, buf);\n#else\n  fort_pseudo_random_data(size, buf);\n#endif\n  ressu_genbytes(size, buf);\n}\n\nvoid fort_internal_random_data_3(int size, char *buf)\n{\n#ifdef FORT_XOR_VERSION\n  fort_random_data_xor(size, buf);\n#else\n  fort_random_data(size, buf);\n#endif\n}\n\nstatic IUTIME fort_next_localmix = 0;\n\/\/#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60\n#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60\n\n#ifdef FORT_USE_WEB  \nstatic IUTIME fort_next_webmix = 0;\n\/\/#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600\n#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600\n#endif\n\n#define RANDOMNESS_IN_ALPHABETS 2\n\n#define DEBUG65 2\n\nvoid fort_strrepl(unsigned char *dest,unsigned char *oldstring, unsigned char *newstring)\n{\n  unsigned char *stringstart;\n#ifdef DEBUG65\n  if(verbose) {  \n    fprintf(stdout,\"fort_strrepl(): oldstring:%s\", oldstring);\n    fprintf(stdout,\", newstring:%s\", newstring);\n    fprintf(stdout,\", olddest:%s\", dest);\n  }\n#endif\n  if((stringstart = strstr(dest, oldstring)) != NULL) {\n    memmove(stringstart + strlen(newstring),\n\t    stringstart + strlen(oldstring),\n\t    strlen(stringstart + strlen(oldstring)) + 1);\n    memmove(stringstart, newstring, strlen(newstring));\n  }\n#ifdef DEBUG65\n  if(verbose) {  \n    fprintf(stdout,\", newdest:%s\", dest);\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n}\n\nvoid fort_mix()\n{\n  int webmix, localmix;\n  unsigned char temp&#91;64];\n\n  IUTIME seconds;\n\n  seconds = getseconds();\n  \n  webmix = 0;\n  localmix = 0;\n\n#ifdef FORT_USE_WEB  \n  if(fort_next_webmix == 0 ||\n     fort_next_webmix &lt;= seconds) {\n    fort_next_webmix = seconds + FORT_SECONDS_BETWEEN_WEBMIXES;\n    fort_next_localmix = seconds + FORT_SECONDS_BETWEEN_LOCALMIXES;\n    webmix = 1;\n    localmix = 1;\n  }\n#endif\n  \n  if(fort_next_localmix == 0 ||\n     fort_next_localmix &lt;= seconds) {\n    fort_next_localmix = seconds + FORT_SECONDS_BETWEEN_LOCALMIXES;\n    localmix = 1;\n  }\n\n  if(!webmix &amp;&amp; !localmix)\n    return;\n  \n  if(verbose) {  \n    char timebuf&#91;128];\n    strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t     localtime((time_t *)&amp;seconds));\n    fprintf(stdout,\"Fort mix time:      %s\\n\", timebuf);\n\n#ifdef FORT_USE_WEB\n    if(fort_use_web) {\n      strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t       localtime((time_t *)&amp;fort_next_webmix));\n      fprintf(stdout,\"Next fort webmix:   %s\\n\", timebuf);\n    }\n#endif\n\n    strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t     localtime((time_t *)&amp;fort_next_localmix));\n    fprintf(stdout,\"Next fort localmix: %s\\n\", timebuf);\n  }\n  \n  fort_internal_random_data_1(sizeof(temp), temp);\n  fort_reseed(sizeof(temp), temp);\n  \n#if defined FORT_USE_WEB || \\\n  defined USE_RDRAND || \\\n  defined USE_RDSEED || \\\n  defined USE_NEWRESSU_COMMAND\n  unsigned char digest&#91;HashLen];\n#endif    \n  \n#ifdef FORT_USE_WEB\n  if(webmix &amp;&amp; fort_use_web) {\n    char *webpages&#91;] = {\n      \"https:\/\/moijari.com:5001\/\",\n      \"https:\/\/moijari.com:5005\/\",\n      \"https:\/\/moijari.com:5006\/\",\n    };\n\n    for(int c = 0; c &lt; sizeof(webpages) \/ sizeof(webpages&#91;0]); c++) {\n      unsigned char *p;\n      \n      unsigned char scheme&#91;32];\n      unsigned char host&#91;32];\n      unsigned char port&#91;10];\n      unsigned char rest&#91;128];\n      \n      p = webpages&#91;c];\n      parse_string(scheme, sizeof(scheme), &amp;p);\n      \n      if(check_string(\":\/\/\", p)) {\n\tp += 3;\n\tparse_string(host, sizeof(host), &amp;p);\n      } else {\n\tstrcpy(host, scheme);\n\tstrcpy(scheme,\"http\");\n      }\n      \n      if(check_string(\":\", p)) {\n\tp++;\n\tparse_string(port, sizeof(port), &amp;p);\n      } else {\n\tstrcpy(port,\"80\");\n      }\n      \n      if(*p != '\/') \n\tstrcpy(rest, \"\/\");\n      else\n\tstrcpy(rest, p);\n      \n      if(verbose) {    \n\tfprintf(stdout,\"URL:%s \", webpages&#91;c]);\n\tfprintf(stdout,\"&#91;scheme:%s]\", scheme);\n\tfprintf(stdout,\"&#91;host:%s]\", host);\n\tfprintf(stdout,\"&#91;port:%s]\", port);\n\tfprintf(stdout,\"&#91;rest:%s]\", p);\n\tfflush(stdout);\n      }\n      \n      if(!strcmp(scheme,\"http\")) {\n\tfort_hash_http_page(host, port, p, digest);\n      } else if(!strcmp(scheme,\"https\")) {\n\tfort_hash_https_page(host, port, p, digest);\n      }\n      fort_reseed(sizeof(digest), digest);\n    }\n  }\n#endif \/\/ #ifdef FORT_USE_WEB\n    \n  if(localmix) {    \n#ifdef FORT_USE_URANDOM\n    memset(temp, 0, sizeof(temp));\n    fort_readfile_xor(sizeof(temp), temp,\n\t\t      \"\/dev\/urandom\");\n    fort_reseed(sizeof(temp), temp);\n#endif\n  \n#ifdef FORT_USE_RANDOM\n    memset(temp, 0, sizeof(temp));\n    fort_readfile_xor(sizeof(temp), temp,\n\t\t      \"\/dev\/random\");\n    fort_reseed(sizeof(temp), temp);\n#endif\n\n#if defined USE_RDRAND || \\\n  defined USE_RDSEED\n    HashCtx hash;\n    unsigned char digest&#91;HashLen];\n#endif\n    \n#ifdef USE_RDRAND\n\n    memset(temp, 0, sizeof(temp));\n    if(rdrand_bytes(sizeof(temp), temp)) {\n      \n      HashInit(&amp;hash);\n      \n      hash_update_cvar(&amp;hash);\n      hash_update_ressu(&amp;hash);\n\n      HashUpdate(&amp;hash, temp, sizeof(temp));\n      HashFinal(digest, &amp;hash);\n      \n      if(verbose) {\n\tfprintf(stdout,\", data: \");\n\tfor(int c = 0; c &lt; sizeof(temp); c++) {\n\t  fprintf(stdout,\"%02x\", temp&#91;c]);\n\t}\n\tfprintf(stdout,\", sha256: \");\n\tfor(int c = 0; c &lt; HashLen; c++) {\n\t  fprintf(stdout,\"%02x\", digest&#91;c]);\n\t}\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n\n\tnewressu_output = 0;\n      }\n      \n      fort_reseed(sizeof(digest), digest);\n    }  \n    \n#endif \/\/ #ifdef USE_RDRAND\n  \n#ifdef USE_RDSEED\n  \n    memset(temp, 0, sizeof(temp));\n    if(rdseed_bytes(sizeof(temp), temp)) {\n      \n      HashInit(&amp;hash);\n\n      hash_update_cvar(&amp;hash);\n      hash_update_ressu(&amp;hash);\n      \n      HashUpdate(&amp;hash, temp, sizeof(temp));\n      HashFinal(digest, &amp;hash);\n      \n      if(verbose) {\n\tfprintf(stdout,\", data: \");\n\tfor(int c = 0; c &lt; sizeof(temp); c++) {\n\t  fprintf(stdout,\"%02x\", temp&#91;c]);\n\t}\n\tfprintf(stdout,\", sha256: \");\n\tfor(int c = 0; c &lt; HashLen; c++) {\n\t  fprintf(stdout,\"%02x\", digest&#91;c]);\n\t}\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n\n\tnewressu_output = 0;\n      }\n      \n      fort_reseed(sizeof(digest), digest);\n    }\n\n#endif \/\/ #ifdef USE_RDSEED\n\n#ifdef FORT_USE_NEWRESSU_COMMAND\n\n    char *commands&#91;] = {\n      \"$newressu -2 -s8 -w8 -l1 --lineno\",\n      \"$newressu -2 -s8 -w8 -l1 --lineno --fast\",\n      \"$newressu -2 -s8 -w8 -l1 --lineno --urandom\",\n#ifdef USE_RDRAND\n      \"$newressu -2 -s8 -w8 -l1 --lineno --rdrand\",\n#endif\n#ifdef USE_RDSEED\n      \"$newressu -2 -s8 -w8 -l1 --lineno --rdseed\",\n#endif\n      \"$newressu -2 -s8 -w8 -l1 --lineno --pseudoressu\",\n#ifdef RANDOMNESS_IN_ALPHABETS\n      \"$newressu --cn -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --deu -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --dnk -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --eng -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --est -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --fin -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --fra -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --gbr -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --got -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --grc -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --ita -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --jp -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --jp1 -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --jp2 -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --jp3 -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --kor -s8 -w4 -l1 --lineno --single\",\n      \"$newressu --ltu -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --lva -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --nor -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --rus -s8 -w8 -l1 --lineno --single\",\n      \"$newressu --swe -s8 -w8 -l1 --lineno --single\",\n#endif\n    };\n\n    for(int c = 0; c &lt; sizeof(commands) \/ sizeof(commands&#91;0]); c++) {\n      if(strstr(commands&#91;c], \"--fort\")) {\n\tfprintf(stderr,\"%s: fort_mix(): cannot call fort recursively \\\"%s\\\"\\n\",\n\t\tprocname, commands&#91;c]);\n      } else {\n\tunsigned char command&#91;256];\n\tstrcpy(command, commands&#91;c]);\n\n\t\/\/ string:$newressu, newstring:\/bin\/newressu2, olddest:$newressu -2 -s8 -w8 -l1 --lineno, newdest:\/bin\/newressu2 -2 -s8 -w8 -l1 --lineno\n\n\tif(strstr(procname,\"newressu\") &amp;&amp; strlen(procname) &lt; 32)\n\t  fort_strrepl(command, \"$newressu\", procname);\n\telse\n\t  fort_strrepl(command, \"$newressu\", \"\/bin\/newressu\");\n\n\tfort_hash_command(command, digest);\n\tfort_reseed(sizeof(digest), digest);\n      }\n    }\n#endif \/\/ #ifdef FORT_USE_NEWRESSU_COMMAND\n  }\n}\n\nvoid file_digest(char *filename,unsigned char temp&#91;HashLen])\n{\n  int c;\n  unsigned char buffer&#91;1024];\n  FILE *fp1;\n  HashCtx ctx;\n  \n  HashInit(&amp;ctx);\n  if((fp1 = fopen(filename, \"rb\")) != NULL) {\n    while((c = fread(buffer, 1, sizeof(buffer), fp1)) &gt; 0)\n      HashUpdate(&amp;ctx, buffer, c);\n    fclose(fp1);\n  }\n  HashFinal(temp, &amp;ctx);\n}\n\n#define DEBUG88\n\nvoid fort_init()\n{\n  int c;\n  unsigned char temp32&#91;32];\n\n  memset(temp32, 0, sizeof(temp32));\n  memset(fort_bytes, 0, sizeof(fort_bytes));\n  memset(fort_key, 0, sizeof(fort_key));\n  \n  if(verbose) {\n    fprintf(stdout,\"hash: %s\",\n\t    HashName);\n    fprintf(stdout,\", pools: %d*%ld\", FORT_POOLS,\n\t    sizeof(struct fort_pool));\n    fprintf(stdout,\", HashCtx: %ld\",\n\t    sizeof(HashCtx));\n    fprintf(stdout,\", hashsize: %d\",\n\t    HashLen);\n    fprintf(stdout,\"\\n\");\n  }\n  \n  unsigned int save_fort_internal_events;\n  save_fort_internal_events = fort_internal_events;\n  fort_internal_events = 1;\n\n  fort_next_save = 0;\n  \n  clearcvar();\n\n  \/\/ Initialize buffers\n\n  for(c = 0; c &lt; FORT_POOLS; c++) {\n    fort_pools&#91;c].length = 0;\n    HashInit(&amp;fort_pools&#91;c].pool);\n  }\n  \n  \/\/ first key to fort_key\n  \n  fort_internal_random_data_1(sizeof(fort_key), fort_key);\n\n#ifdef ADDITIONAL_SECRETS  \n\n  \/\/ additional constant randomness from program\n\n  fort_reseed(strlen(copyright), copyright);\n  fort_reseed(strlen(programname), programname);\n\n  unsigned char filedigest&#91;HashLen];\n  file_digest(\"\/proc\/self\/exe\", filedigest);\n  fort_reseed(strlen(filedigest), filedigest);\n  \n  fort_reseed(strlen(program_secret), program_secret);\n\n  \/\/ additional constant randomness\n  \/\/ from you (one more secret adversary\n  \/\/ has to guess)\n\n  FILE *fp1;\n  if((fp1 = fopen(fort_secret_file, \"r\")) != NULL) {\n    fclose(fp1);\n  } else {\n    if((fp1 = fopen(fort_secret_file, \"w\")) != NULL) {\n      fprintf(fp1,\"Your secret additional constant data to fort:\\n\");\n      fclose(fp1);\n      unsigned char temp2&#91;160];\n      sprintf(temp2,\"%s -2 -l1 &gt;&gt;%s\", procname, fort_secret_file);\n      system(temp2);\n      fprintf(stdout,\"File %s written\\n\", fort_secret_file);\n    }\n  }\n  fort_reseed_file(fort_secret_file);\n\n#endif\n  \n#ifdef DEBUG10\n\n  FILE *fp1;\n  \n  \/\/ Empty events file\n\n  if((fp1 = fopen(fort_events_file, \"w\"))!=NULL)\n    fclose(fp1);\n  event_id = 0;\n\n#endif \/\/ #ifdef DEBUG10\n\n  \/\/ Mix fort key with web + local\n  \/\/ random numbers\n  \n  fort_mix();\n\n  for(c = 0; c &lt; FORT_POOLS; c++) {\n    FORT_INTERNAL_EVENTS_START(31)\n    fort_internal_random_data_2(sizeof(temp32), temp32);\n    hash_update(&amp;fort_pools&#91;c].pool,\n      temp32, sizeof(temp32));\n    FORT_INTERNAL_EVENTS_END(32)\n  }\n\n#ifdef FORT_INTERNAL_EVENTS\n\n  if(fort_internal_events) {\n\n    \/\/ Create some internal events\n\n    for(c=0; c&lt;32; c++) {\n      FORT_INTERNAL_EVENTS_START(34)\n      fort_internal_random_data_3(sizeof(temp32), temp32);\n      FORT_INTERNAL_EVENTS_END(35)\n    }\n  }\n\n#endif \/\/ #ifdef FORT_INTERNAL_EVENTS\n\n  fort_reseed_count = 0;\n  fort_next_reseed = 0;\n\n  \/\/ Reseed fort_key with new events\n\n  fort_internal_random_data_3(sizeof(temp32), temp32);\n  fort_reseed(sizeof(temp32), temp32);\n\n  fort_restore();\n\n  \/\/ Forget temp\n\n  memset(temp32, 0, sizeof(temp32));\n\n  fort_internal_events = save_fort_internal_events;\n\n  \/\/fort_reseed_count = 0;\n  \/\/fort_next_reseed = 0;\n\n  fort_next_save = 1;\n}\n\nvoid fort_version()\n{\n  fprintf(stderr,\"%s\", programname); \/\/ touch these outside MAIN\n  fprintf(stderr,\", %s\\n\", copyright);\n}\n\n#define aMAIN 2\n#ifdef MAIN\n\nunsigned char *procname;\n\nint main(int argc, char *argv&#91;])\n{\n  procname = argv&#91;0];\n  fort_version();\n  fort_init();\n  return(0);\n}\n\n#endif \/\/ #ifdef MAIN<\/code><\/pre>\n\n\n\n<p>fort.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Perustuu Bruce Schneierin kirjassa esitt\u00e4m\u00e4\u00e4n fortuna j\u00e4rjestelm\u00e4\u00e4n.\n * Written by Jari Kuivaniemi\n *\/\n\n#ifndef SHA256_H\n#include \"sha256.h\"\n#endif\n\n#define aUSE_RDRAND 2\n#define aUSE_RDSEED 2\n\ntypedef unsigned long long IUTIME;\n\nextern int fort_verbose;\nextern int fort_partial_line;\nextern int fort_use_web;\n\nextern unsigned char fort_random_file&#91;128];\nextern unsigned char fort_secret_file&#91;128];\nextern unsigned char fort_pools_file&#91;128];\n#ifdef DEBUG10\nstatic char fort_events_file&#91;128] = \"fortevents.deb\";\n#endif\nunsigned char cvar&#91;16];\nint cvarsize;\n\nvoid inccvar();\nvoid clearcvar();\nvoid hash_update_cvar(HashCtx *hash);\n\nvoid fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf);\nvoid fort_add_random_event_timer_start(IUTIME *micros);\nvoid fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *millis);\nvoid fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf,int size);\nvoid fort_add_random_event_time(int *pool, int source, int mode);\nvoid fort_rekey(unsigned char *buf);\nvoid fort_pseudo_random_data(int len,unsigned char *buf);\nvoid fort_pseudo_random_data_xor(int len,unsigned char *buf);\nvoid fort_reseed(int len,unsigned char *buf);\nvoid fort_random_data(int len,unsigned char *buf);\nvoid fort_random_data_xor(int len,unsigned char *buf);\nint fort_random_data_byte();\nvoid fort_clear();\nint fort_random_data_byte_limit(int limit);\nvoid fort_random_data_buffer(int size, unsigned char *buffer);\nvoid fort_save();\nvoid fort_read_file();\nvoid fort_mix();\nvoid fort_init();\nvoid hash_init(HashCtx *hash);\nvoid hash_update(HashCtx *hash, unsigned char *data, int len);\nvoid hash_final(unsigned char digest&#91;HashLen], HashCtx *hash);\n\nvoid fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);\nvoid fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);\n\nvoid fort_hash_command(unsigned char *command, unsigned char *hash);\n\nint rdrand_bytes(int buflen, unsigned char *buf);\nint rdseed_bytes(int buflen, unsigned char *buf);\n\n#ifdef FORT_INTERNAL_EVENTS\n#define FORT_INTERNAL_EVENTS_START(source) \\\n  IUTIME micros;                           \\\n  static int \\\n    pool=0, pool2=0; \\\n  if(fort_internal_events) { \\\n    fort_add_random_event_time(&amp;pool, \\\n    source, fort_internal_event_mode); \\\n    fort_add_random_event_timer_start(&amp;micros); \\\n  }\n#else\n#define FORT_INTERNAL_EVENTS_START(source)\n#endif\n\n#ifdef FORT_INTERNAL_EVENTS\n#define FORT_INTERNAL_EVENTS_END(source) \\\n  if(fort_internal_events) \\\n    fort_add_random_event_timer_do(&amp;pool2, \\\n      source, fort_internal_event_mode, \\\n      &amp;micros);\n#else\n#define FORT_INTERNAL_EVENTS_END(source)\n#endif\n\n#ifdef FORT_EVENTS\n#define FORT_EVENTS_START(source) \\\n  IUTIME micros;                           \\\n  static int \\\n    pool=0, pool2=0; \\\n  if(fort_events) { \\\n    fort_add_random_event_time(&amp;pool, \\\n    source, fort_event_mode); \\\n    fort_add_random_event_timer_start(&amp;micros); \\\n  }\n#else\n#define FORT_EVENTS_START(source)\n#endif\n\n#ifdef FORT_EVENTS\n#define FORT_EVENTS_END(source) \\\n  if(fort_events) \\\n    fort_add_random_event_timer_do(&amp;pool2, \\\n      source, fort_event_mode, \\\n      &amp;micros);\n#else\n#define FORT_EVENTS_END(source)\n#endif<\/code><\/pre>\n\n\n\n<p>sha256.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Written from SHA256 documents by Jari Kuivaniemi, read \"http:\/\/en.wikipedia.org\/wiki\/SHA-2\" *\/\n#include &lt;stdio.h&gt;\n#include &lt;memory.h&gt;\n#include &lt;string.h&gt;\n\n#include \"sha256.h\"\n\nextern unsigned char *procname;\n\n\/\/#ifdef MAIN \/\/ in Makefile\n\nunsigned char *sha_name = \"SHA256 v1.0\";\n\nvoid SHA256Init(SHA256_CONTEXT *sha256)\n{\n  sha256-&gt;state&#91;0] = 0x6a09e667;\n  sha256-&gt;state&#91;1] = 0xbb67ae85;\n  sha256-&gt;state&#91;2] = 0x3c6ef372;\n  sha256-&gt;state&#91;3] = 0xa54ff53a;\n  sha256-&gt;state&#91;4] = 0x510e527f;\n  sha256-&gt;state&#91;5] = 0x9b05688c;\n  sha256-&gt;state&#91;6] = 0x1f83d9ab;\n  sha256-&gt;state&#91;7] = 0x5be0cd19;\n  \n  sha256-&gt;count = 0;\n}\n\nIUWORD k256&#91;64] = {\n  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n};\n\n#define RR32(word,bits) ( ((word) &gt;&gt; (bits)) | ((word) &lt;&lt; (32 - (bits))) )\n#define RS32(word,bits) ( ((word) &gt;&gt; (bits)) )\n\nvoid SHA256Transform(IUWORD state&#91;8], IUBYTE buffer&#91;64])\n{\n  int i;\n  \n  IUWORD w&#91;64], s0;\n  IUWORD a, b, c, d, e, f, g, h;\n  IUWORD maj, t2, s1;\n  IUWORD ch, t1;\n  \n  for(i = 0; i &lt; 16; i++) {\n    w&#91;i] =\n      (IUWORD)buffer&#91;i * 4 + 0] &lt;&lt; 24 |\n      (IUWORD)buffer&#91;i * 4 + 1] &lt;&lt; 16 |\n      (IUWORD)buffer&#91;i * 4 + 2] &lt;&lt; 8  |\n      (IUWORD)buffer&#91;i * 4 + 3];\n  }\n  \n  for(i=16;i&lt;64;i++) {\n    s0 = (RR32(w&#91;i - 15], 7)) ^ (RR32(w&#91;i - 15], 18)) ^ (RS32(w&#91;i - 15], 3));\n    s1 = (RR32(w&#91;i - 2], 17)) ^ (RR32(w&#91;i - 2], 19)) ^ (RS32(w&#91;i - 2], 10));\n    w&#91;i] = w&#91;i - 16] + s0 + w&#91;i - 7] + s1;\n  }\n  \n  a = state&#91;0];\n  b = state&#91;1];\n  c = state&#91;2];\n  d = state&#91;3];\n  e = state&#91;4];\n  f = state&#91;5];\n  g = state&#91;6];\n  h = state&#91;7];\n  \n  for(i=0;i&lt;64;i++) {\n    s0 = (RR32(a, 2)) ^ (RR32(a, 13)) ^ (RR32(a, 22));\n    maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    t2 = s0 + maj;\n    s1 = (RR32(e, 6)) ^ (RR32(e, 11)) ^ (RR32(e, 25));\n    ch = (e &amp; f) ^ ((~ e) &amp; g);\n    t1 = h + s1 + ch + k256&#91;i] + w&#91;i];\n    \n    h = g;\n    g = f;\n    f = e;\n    e = d + t1;\n    d = c;\n    c = b;\n    b = a;\n    a = t1 + t2;\n  }\n  \n  state&#91;0] = state&#91;0] + a;\n  state&#91;1] = state&#91;1] + b;\n  state&#91;2] = state&#91;2] + c;\n  state&#91;3] = state&#91;3] + d;\n  state&#91;4] = state&#91;4] + e;\n  state&#91;5] = state&#91;5] + f;\n  state&#91;6] = state&#91;6] + g;\n  state&#91;7] = state&#91;7] + h;\n}\n\nvoid SHA256Update(SHA256_CONTEXT *sha256, unsigned char *data, int len)\n{\n  int i, j;\n  \n  j = (int)sha256-&gt;count &amp; 63;\n  \n  sha256-&gt;count += len;\n  \n  if((j + len) &gt; 63) {\n    memcpy(&amp;sha256-&gt;buffer&#91;j], data, 64 - j); \/* last bytes of next block *\/\n    \n    SHA256Transform(sha256-&gt;state, sha256-&gt;buffer);\n    for (i = 64 - j ; i + 63 &lt; len; i += 64) {\n      SHA256Transform(sha256-&gt;state, &amp;data&#91;i]);\n    }\n    j = 0;\n  } else\n    i = 0;\n  \n  memcpy(&amp;sha256-&gt;buffer&#91;j], &amp;data&#91;i], len - i);\n}\n\nvoid SHA256Final(unsigned char digest&#91;32], SHA256_CONTEXT *sha256)\n{\n  int i, j;\n  unsigned char filelenght&#91;8];\n  IULONG count;\n  \n  count = sha256-&gt;count &lt;&lt; 3;\n  SHA256Update(sha256, \"\\200\", 1);\n  \n  while((sha256-&gt;count &amp; 63) != 56)\n    SHA256Update(sha256, \"\\0\", 1);\n  \n  filelenght&#91;0] = (unsigned char)(count &gt;&gt; 56) &amp; 0xff;\n  filelenght&#91;1] = (unsigned char)(count &gt;&gt; 48) &amp; 0xff;\n  filelenght&#91;2] = (unsigned char)(count &gt;&gt; 40) &amp; 0xff;\n  filelenght&#91;3] = (unsigned char)(count &gt;&gt; 32) &amp; 0xff;\n  filelenght&#91;4] = (unsigned char)(count &gt;&gt; 24) &amp; 0xff;\n  filelenght&#91;5] = (unsigned char)(count &gt;&gt; 16) &amp; 0xff;\n  filelenght&#91;6] = (unsigned char)(count &gt;&gt; 8 ) &amp; 0xff;\n  filelenght&#91;7] = (unsigned char)(count &amp; 0xff);\n  \n  SHA256Update(sha256, filelenght, sizeof(filelenght));\n  \n  for(i = 0, j = 0; i &lt; 8; i++) {\n    digest&#91;j++] = (unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 24) &amp; 0xff;\n    digest&#91;j++] = (unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 16) &amp; 0xff;\n    digest&#91;j++] = (unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 8) &amp; 0xff;\n    digest&#91;j++] = (unsigned char) (sha256-&gt;state&#91;i] ) &amp; 0xff;\n  }\n}\n\n#ifdef MAIN\n\nvoid printhex(char *name, unsigned char *digest, int len)\n{\n  int c;\n\n  fprintf(stdout,\"%s=\", name);\n  for(c = 0; c &lt; len; c++) {\n    fprintf(stdout,\"%02x\", digest&#91;c]);\n  }\n  fflush(stdout);\n}\n\nint shahexdigit(int c)\n{\n  if(c &gt;= '0' &amp;&amp; c &lt;= '9') return(c - '0');\n  else if(c &gt;= 'a' &amp;&amp; c &lt;= 'f') return(c - 'a' + 10);\n  else if(c &gt;= 'A' &amp;&amp; c &lt;= 'F') return(c - 'A' + 10);\n  return(0);\n}\n\nvoid sha_test()\n{\n  int c, d, e, ok, allok;\n  SHA256_CONTEXT sha256;\n  unsigned char result&#91;32], *p;\n  \n  fprintf(stdout,\"%s\", sha_name);\n  fprintf(stdout,\", Context size: %ld\", sizeof(SHA256_CONTEXT));\n  fprintf(stdout,\", Hash size: 32\");\n  fprintf(stdout,\", IUBYTE size: %ld\", sizeof(IUBYTE));\n  fprintf(stdout,\", IUWORD size: %ld\", sizeof(IUWORD));\n  fprintf(stdout,\", IULONG size: %ld\", sizeof(IULONG));\n\n  struct test {\n    unsigned char *string;\n    int count;\n    unsigned char *result;\n  } tests&#91;] = {\n    { \"abc\", 1, \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\" },\n    { \"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\", 1, \"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1\" },\n    { \"a\", 1000000, \"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0\" },\n    { \"The quick brown fox jumps over the lazy dog\", 1, \"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592\" },\n  };\n\n  allok = 1;\n  for(c = 0; c &lt; sizeof(tests) \/ sizeof(tests&#91;0]); c++) {\n    SHA256Init(&amp;sha256);\n    for(d = 0; d &lt; tests&#91;c].count; d++)\n      SHA256Update(&amp;sha256, tests&#91;c].string, strlen(tests&#91;c].string));\n    SHA256Final(result, &amp;sha256);\n    p = tests&#91;c].result;\n    d = 0;\n    ok = 1;\n    while(*p != '\\0') {\n      if(*p != '\\0')\n\te = shahexdigit(*p++);\n      if(*p!='\\0')\n\te = e * 16 + shahexdigit(*p++);\n      if(e != result&#91;d])\n\tok = 0;\n      d++;\n    }\n    if(ok) {\n      fprintf(stdout,\"\\nsha256 test \");\n      fprintf(stdout,\"string: %s\", tests&#91;c].string);\n      fprintf(stdout,\", count: %d, \", tests&#91;c].count);\n      printhex(\"tmp32\", result, sizeof(result));\n      fprintf(stdout,\", result: %s\", tests&#91;c].result);\n      fprintf(stdout,\" ok!!!!\");\n      fflush(stdout);\n    } else {\n      fprintf(stdout,\"\\nsha256 test \");\n      fprintf(stdout,\"string: %s\", tests&#91;c].string);\n      fprintf(stdout,\", count: %d, \", tests&#91;c].count);\n      printhex(\"tmp32\", result, sizeof(result));\n      fprintf(stdout,\", result: %s\", tests&#91;c].result);\n      fprintf(stdout,\" failed!!!!\");\n      fflush(stdout);\n      allok = 0;\n    }\n  }\n  if(allok) {\n    fprintf(stdout,\", sha256 tests ok!!!!\\n\");\n  } else {\n    fprintf(stdout,\", sha256 tests failed!!!!\\n\");\n  }\n  fflush(stdout);\n}\n\nint main(int argc, char *argv&#91;])\n{\n  sha_test();\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>sha256.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifndef SHA256_H\n#define SHA256_H\n\n#define HashName   \"SHA256\"\n#define HashInit   SHA256Init\n#define HashUpdate SHA256Update\n#define HashFinal  SHA256Final\n#define HashLen    32\n#define HashCtx    SHA256_CONTEXT\n\ntypedef unsigned char IUBYTE;\ntypedef unsigned int IUWORD;\ntypedef unsigned long long IULONG;\n\ntypedef struct {\n    IUWORD state&#91;8];\n    IULONG count;\n    IUBYTE buffer&#91;64];\n} SHA256_CONTEXT;\n\nvoid SHA256Init(SHA256_CONTEXT *sha256);\nvoid SHA256Update(SHA256_CONTEXT* sha256, unsigned char *data, int len);\nvoid SHA256Final(unsigned char digest&#91;32], SHA256_CONTEXT *sha256);\n\nvoid sha_test();\n\n#endif<\/code><\/pre>\n\n\n\n<p>intelrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;memory.h&gt;\n\n#include \"fort.h\"\n#include \"newressu.h\"\n\n#if defined USE_RDRAND ||\t\t\t\\\n    defined USE_RDSEED\n\n\/\/ see: https:\/\/software.intel.com\/content\/www\/us\/en\/develop\/articles\/intel-digital-random-number-generator-drng-software-implementation-guide.html\n\nvoid _cpuid(unsigned int leaf, unsigned int subleaf,\n\t    unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)\n{\n  asm volatile(\"cpuid\"\n\t       : \"=a\" (*a), \"=b\" (*b), \"=c\" (*c), \"=d\" (*d)\n\t       : \"a\" (leaf), \"c\" (subleaf) );\n}\n\nint _is_cpu_vendor(unsigned char *cpuvendor)\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(0, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n\n  if(memcmp((char *)(&amp;b), cpuvendor,4) == 0 &amp;&amp;\n     memcmp((char *)(&amp;d), cpuvendor+4,4) == 0 &amp;&amp;\n     memcmp((char *)(&amp;c), cpuvendor+8,4) == 0)\n    ok = 1;\n\n  return(ok);\n}\n\n#endif\n\n#ifdef USE_RDRAND\n\nint _has_rdrand()\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(1, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((c &amp; 0x40000000) == 0x40000000) {\n    ok = 1;\n  }\n\n  return(ok);\n}\n\nint _rdrand_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdrand %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdrand_bytes(int buflen, unsigned char *buf)\n{\n  int c, n, ret = 0;\n  unsigned long l;\n\n  if(verbose) {\n    if(newressu_output == 1)\n      fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdrand()) {\n    if(verbose)\n      fprintf(stdout,\"Intel rdrand\");\n    ret = 1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdrand()) {\n    if(verbose)\n      fprintf(stdout,\"AMD rdrand\");\n    ret = 1;\n  }\n  \n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries = 0;\n\n      while(++tries &lt; 100) {\n\tif((ret = _rdrand_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n\t\/\/fprintf(stdout,\" %016lu\",l);\n      }\n\n      if(verbose) {\n\tfprintf(stdout,\", t:%d \", tries);\n\tnewressu_output = 1;\n      }\n\n      if(ret == 0)\n\tbreak;\n\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n\n      if(verbose) {\n\tfor(c = 0; c &lt; sizeof(l); c++)\n\t  fprintf(stdout,\"%02x\", ((unsigned char *)&amp;l)&#91;c]);\n\tnewressu_output = 1;\n      }\n\n      memcpy(buf, (unsigned char *)&amp;l, n);\n\n      buf += n;\n      buflen -= n;\n    }\n  }\n\n  if(verbose &amp;&amp; newressu_output) {\n    fprintf(stdout, \"\\n\");\n    newressu_output = 0;\n  }\n\n  return(ret);\n}\n\n#endif \/\/ #ifdef USE_RDRAND\n\n#ifdef USE_RDSEED\n\nint _has_rdseed()\n{\n  int ok = 0;\n  unsigned int a, b, c, d;\n\n  _cpuid(7, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((b &amp; 0x40000) == 0x40000) {\n    ok = 1;\n  }\n\n  return(ok);\n}\n\nint _rdseed_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdseed %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdseed_bytes(int buflen, unsigned char *buf)\n{\n  int c, n, ret = 0;\n  unsigned long l;\n\n  if(verbose) {\n    if(newressu_output == 1)\n      fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdseed()) {\n    if(verbose)\n      fprintf(stdout,\"Intel rdseed\");\n    ret = 1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdseed()) {\n    if(verbose)\n      fprintf(stdout,\"AMD rdseed\");\n    ret = 1;\n  }\n\n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries = 0;\n\n      while(++tries &lt; 1000) {\n\tif((ret = _rdseed_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n\t\/\/fprintf(stdout,\" %lu\",l);\n      }\n\n      if(verbose) {\n\tfprintf(stdout,\", t:%d \", tries);\n      }\n\n      if(ret == 0)\n\tbreak;\n\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n\n      if(verbose) {\n\tfor(c = 0; c &lt; sizeof(l); c++)\n\t  fprintf(stdout,\"%02x\",((unsigned char *)&amp;l)&#91;c]);\n\tnewressu_output = 1;\n      }\n\n      memcpy(buf, (unsigned char *)&amp;l, n);\n\n      buf += n;\n      buflen -= n;\n    }\n  }\n\n  if(verbose &amp;&amp; newressu_output) {\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0;\n  }\n  \n  return(ret);\n}\n\n#endif \/\/ #ifdef USE_RDSEED<\/code><\/pre>\n\n\n\n<p>webrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;memory.h&gt;\n#include &lt;errno.h&gt;\n\n#include &lt;openssl\/ssl.h&gt;\n#include &lt;openssl\/err.h&gt;\n\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n#include &lt;netdb.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n\n#include \"sha256.h\"\n#include \"fort.h\"\n\nextern unsigned char *procname;\nextern int newressu_output; \nextern int verbose;\n\n#include &lt;stdarg.h&gt;\n\nvoid dbs_printf(unsigned char **buf, size_t *buf_length, const unsigned char *format, ...)\n{\n  int count;\n  va_list args;;\n  \n  va_start(args, format);\n  count = vsnprintf(*buf, *buf_length, format, args) + 1;\n  va_end(args);\n  if(*buf_length &lt; count) {\n    *buf_length = count;\n    *buf = realloc(*buf, *buf_length);\n    va_start(args, format);\n    count = vsnprintf(*buf, *buf_length, format, args) + 1;\n    va_end(args);\n  }\n}\n\nint fort_connect(unsigned char *host, unsigned char *port)\n{\n  struct addrinfo hints, *res, *resp;\n  int s, status;\n  \n  memset(&amp;hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;\n  hints.ai_socktype = SOCK_STREAM;\n  hints.ai_flags = AI_PASSIVE;\n  \n  if((status = getaddrinfo(host, port, &amp;hints, &amp;res)) != 0) {\n    fprintf(stderr,\"\\n%s: getaddrinfo\", procname);\n    fprintf(stderr,\", status %d\", status);\n    fprintf(stderr,\", gai_strerror(): %s\", gai_strerror(status));\n    fprintf(stderr,\", errno %d\\n\", errno);\n    fflush(stderr);\n  }\n  \n  for(resp = res; resp != NULL; resp = resp-&gt;ai_next) {\n    if((s = socket(resp-&gt;ai_family, resp-&gt;ai_socktype, resp-&gt;ai_protocol)) &lt; 0)\n      continue;\n    if(connect(s, resp-&gt;ai_addr, resp-&gt;ai_addrlen) == 0)\n      break;\n    close(s);\n  }\n\n  freeaddrinfo(res);\n\n  return(s);\n}\n\n#define aDEBUG27 2\n\nvoid fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  if((s = fort_connect(host, port))&lt;0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  \/\/ GET \/ HTTP\/1.0\\r\\nHost: moijari.com:5006\\r\\n\n    \n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\" \\\n    \"Host: %s:%s\\r\\n\" \\\n    \"User-Agent: %s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length = 0;\n\n  extern unsigned char *fortuseragent;\n  \n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port, fortuseragent);\n\n  if((status = write(s, msg, strlen(msg))) &lt; 0) {\n    fprintf(stderr, \"\\n%s: write(), error: %d\\n\", procname, errno);\n    perror(\"write\");\n    fflush(stderr);\n  }\n\n  HashCtx ctx;\n  unsigned char buffer&#91;1024];\n\n  HashInit(&amp;ctx);\n\n  bytes = 0;\n  characters = 0;\n\n  while((cnt = read(s, buffer, sizeof(buffer))) &gt; 0) {\n#ifdef DEBUG27\n    write(1, buffer, cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;ctx, buffer, cnt);\n    bytes += cnt;\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n  }\n\n  hash_update_cvar(&amp;ctx);\n  HashFinal(hash, &amp;ctx);\n  if(verbose) {\n    fprintf(stdout,\"\\n, %d bytes read\", bytes);\n    fprintf(stdout,\", %d characters read\", characters);\n    fprintf(stdout,\", sha256: \");\n    for(int c = 0;c &lt; HashLen; c++) {\n      fprintf(stdout,\"%02x\", hash&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0; \n  }\n\n  close(s);\n}\n\n#define aDEBUG49 2\n#define aDEBUG50 2\n\nvoid fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  SSL_METHOD *method = NULL;\n  SSL_CTX *ctx = NULL;\n  SSL *ssl;\n\n  SSL_library_init(); \/\/see: http:\/\/h30266.www3.hpe.com\/odl\/axpos\/opsys\/vmsos84\/BA554_90007\/ch04s03.html\n  OpenSSL_add_ssl_algorithms();\n  SSL_load_error_strings();\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSLv23_client_method()\\n\");\n#endif\n  if((method = (SSL_METHOD *)    \n      SSLv23_client_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_new()\\n\");\n#endif\n  if((ctx = SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_new()\\n\");\n#endif\n  if((ssl = SSL_new(ctx)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"fort_connect()\\n\");\n#endif \n if((s = fort_connect(host, port)) &lt; 0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  SSL_set_fd(ssl, s);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_connect(ssl)\\n\");\n#endif \n  if((status = SSL_connect(ssl)) &lt;= 0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_connect()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\" , errno);\n    fprintf(stderr,\", SSL_get_error(): %d\\n\", SSL_get_error(ssl,status));\n    perror(\"SSL_connect\");\n    fflush(stderr);\n  }\n\n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\" \\\n    \"Host: %s:%s\\r\\n\" \\\n    \"User-Agent: %s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length = 0;\n\n  extern unsigned char *fortuseragent;\n\n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port, fortuseragent);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_write(), msg_length:%ld, msg=\\\"%s\\\"\\n\", msg_length,msg);\n#endif \n  if((status = SSL_write(ssl, msg, strlen(msg))) &lt; 0) {\n    fprintf(stderr,\"\\n%s: SSL_write()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_write\");\n    fflush(stderr);\n  }\n  fflush(stdout);\n  \n  HashCtx hashctx;\n  unsigned char buffer&#91;2048];\n\n  HashInit(&amp;hashctx);\n\n  bytes = 0;\n  characters = 0;\n\n#ifdef DEBUG49\n  fprintf(stdout, \"SSL_read()\\n\");\n#endif\n  int bytesneeded = 0, bytesheader = 0, bytescontent = 0;\n  \n  do {\n    cnt = SSL_read(ssl, buffer, sizeof(buffer));\n    if(cnt &lt; 0) {\n      int err, err2;\n      err = SSL_get_error(ssl, cnt);\n      err2 = ERR_get_error();\n\n      fprintf(stderr, \"\\n%s: cannot SSL_read()\", procname);\n      fprintf(stderr, \", retval: %d\", cnt);\n      fprintf(stderr, \", errno: %d\", errno);\n      fprintf(stderr,\", SSL_get_error() %d\", err);\n      fprintf(stderr,\", ERR_get_error() %d\\n\", err2);\n      perror(\"SSL_read\");\n      fflush(stderr);\n      break;\n    }\n\n#ifdef DEBUG50\n    write(1, buffer, cnt);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes += cnt;\n\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n    if(bytesneeded == 0) {\n      char *p;\n      p = buffer;\n      int count = 0;\n      while(*p != '\\0') {\n\tif(!strncmp(p, \"\\r\\nContent-Length: \", 18)) {\n\t  bytescontent = atoi(p + 18);\n\t}\n\tif(!strncmp(p, \"\\r\\n\\r\\n\", 4)) {\n\t  bytesheader = count;\n\t}\n\tp++;\n\tcount++;\n      }\n      bytesneeded = bytescontent + bytesheader + 4;\n    }\n  } while(SSL_pending(ssl) || bytes &lt; bytesneeded);\n\n  if(verbose) {\n    fprintf(stdout,\"\\nbytescontent:%d\", bytescontent);\n    fprintf(stdout,\", bytesheader:%d\", bytesheader);\n    fprintf(stdout,\", bytesneeded:%d\", bytesneeded);\n    fflush(stdout);\n  }\n#ifdef OLD1\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_read()\\n\");\n#endif \n  while((cnt = SSL_read(ssl, buffer, sizeof(buffer))) &gt; 0) {\n#ifdef DEBUG49\n    fprintf(stdout,\"SSL_read() round\\n\");\n#endif \n    \n#ifdef DEBUG50\n    write(1, buffer, cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes += cnt;\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n  }\n  fflush(stdout);\n  if(cnt &lt; 0) {\n    fprintf(stderr, \"\\n%s: SSL_read()\", procname);\n    fprintf(stderr, \", status: %d\", status);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_read\");\n    fflush(stderr);\n  }\n  \n#endif\n  \n  fflush(stdout);\n\n  hash_update_cvar(&amp;hashctx);\n  HashFinal(hash, &amp;hashctx);\n\n  if(verbose) {\n    fprintf(stdout,\"\\n, %d bytes read\", bytes);\n    fprintf(stdout,\", %d characters read\", characters);\n    fprintf(stdout,\", sha256: \");\n    for(int c = 0;c &lt; HashLen; c++) {\n      fprintf(stdout,\"%02x\", hash&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0; \n }\n#ifdef NOTUSED\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_shutdown()\\n\");\n#endif \n  SSL_shutdown(ssl);\n#endif\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_free()\\n\");\n#endif \n  SSL_free(ssl);\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_free()\\n\");\n#endif \n  SSL_CTX_free(ctx);\n  close(s);\n}<\/code><\/pre>\n\n\n\n<p>commandrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;memory.h&gt;\n#include &lt;errno.h&gt;\n\n#include &lt;openssl\/ssl.h&gt;\n#include &lt;openssl\/err.h&gt;\n\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n#include &lt;netdb.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n\n#include \"sha256.h\"\n#include \"fort.h\"\n\nextern unsigned char *procname;\nextern int newressu_output; \nextern int verbose;\n\n#include &lt;stdarg.h&gt;\n\nvoid dbs_printf(unsigned char **buf, size_t *buf_length, const unsigned char *format, ...)\n{\n  int count;\n  va_list args;;\n  \n  va_start(args, format);\n  count = vsnprintf(*buf, *buf_length, format, args) + 1;\n  va_end(args);\n  if(*buf_length &lt; count) {\n    *buf_length = count;\n    *buf = realloc(*buf, *buf_length);\n    va_start(args, format);\n    count = vsnprintf(*buf, *buf_length, format, args) + 1;\n    va_end(args);\n  }\n}\n\nint fort_connect(unsigned char *host, unsigned char *port)\n{\n  struct addrinfo hints, *res, *resp;\n  int s, status;\n  \n  memset(&amp;hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;\n  hints.ai_socktype = SOCK_STREAM;\n  hints.ai_flags = AI_PASSIVE;\n  \n  if((status = getaddrinfo(host, port, &amp;hints, &amp;res)) != 0) {\n    fprintf(stderr,\"\\n%s: getaddrinfo\", procname);\n    fprintf(stderr,\", status %d\", status);\n    fprintf(stderr,\", gai_strerror(): %s\", gai_strerror(status));\n    fprintf(stderr,\", errno %d\\n\", errno);\n    fflush(stderr);\n  }\n  \n  for(resp = res; resp != NULL; resp = resp-&gt;ai_next) {\n    if((s = socket(resp-&gt;ai_family, resp-&gt;ai_socktype, resp-&gt;ai_protocol)) &lt; 0)\n      continue;\n    if(connect(s, resp-&gt;ai_addr, resp-&gt;ai_addrlen) == 0)\n      break;\n    close(s);\n  }\n\n  freeaddrinfo(res);\n\n  return(s);\n}\n\n#define aDEBUG27 2\n\nvoid fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  if((s = fort_connect(host, port))&lt;0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  \/\/ GET \/ HTTP\/1.0\\r\\nHost: moijari.com:5006\\r\\n\n    \n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\" \\\n    \"Host: %s:%s\\r\\n\" \\\n    \"User-Agent: %s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length = 0;\n\n  extern unsigned char *fortuseragent;\n  \n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port, fortuseragent);\n\n  if((status = write(s, msg, strlen(msg))) &lt; 0) {\n    fprintf(stderr, \"\\n%s: write(), error: %d\\n\", procname, errno);\n    perror(\"write\");\n    fflush(stderr);\n  }\n\n  HashCtx ctx;\n  unsigned char buffer&#91;1024];\n\n  HashInit(&amp;ctx);\n\n  bytes = 0;\n  characters = 0;\n\n  while((cnt = read(s, buffer, sizeof(buffer))) &gt; 0) {\n#ifdef DEBUG27\n    write(1, buffer, cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;ctx, buffer, cnt);\n    bytes += cnt;\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n  }\n\n  hash_update_cvar(&amp;ctx);\n  HashFinal(hash, &amp;ctx);\n  if(verbose) {\n    fprintf(stdout,\"\\n, %d bytes read\", bytes);\n    fprintf(stdout,\", %d characters read\", characters);\n    fprintf(stdout,\", sha256: \");\n    for(int c = 0;c &lt; HashLen; c++) {\n      fprintf(stdout,\"%02x\", hash&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0; \n  }\n\n  close(s);\n}\n\n#define aDEBUG49 2\n#define aDEBUG50 2\n\nvoid fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  SSL_METHOD *method = NULL;\n  SSL_CTX *ctx = NULL;\n  SSL *ssl;\n\n  SSL_library_init(); \/\/see: http:\/\/h30266.www3.hpe.com\/odl\/axpos\/opsys\/vmsos84\/BA554_90007\/ch04s03.html\n  OpenSSL_add_ssl_algorithms();\n  SSL_load_error_strings();\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSLv23_client_method()\\n\");\n#endif\n  if((method = (SSL_METHOD *)    \n      SSLv23_client_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_new()\\n\");\n#endif\n  if((ctx = SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_new()\\n\");\n#endif\n  if((ssl = SSL_new(ctx)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"fort_connect()\\n\");\n#endif \n if((s = fort_connect(host, port)) &lt; 0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  SSL_set_fd(ssl, s);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_connect(ssl)\\n\");\n#endif \n  if((status = SSL_connect(ssl)) &lt;= 0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_connect()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\" , errno);\n    fprintf(stderr,\", SSL_get_error(): %d\\n\", SSL_get_error(ssl,status));\n    perror(\"SSL_connect\");\n    fflush(stderr);\n  }\n\n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\" \\\n    \"Host: %s:%s\\r\\n\" \\\n    \"User-Agent: %s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length = 0;\n\n  extern unsigned char *fortuseragent;\n\n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port, fortuseragent);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_write(), msg_length:%ld, msg=\\\"%s\\\"\\n\", msg_length,msg);\n#endif \n  if((status = SSL_write(ssl, msg, strlen(msg))) &lt; 0) {\n    fprintf(stderr,\"\\n%s: SSL_write()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_write\");\n    fflush(stderr);\n  }\n  fflush(stdout);\n  \n  HashCtx hashctx;\n  unsigned char buffer&#91;2048];\n\n  HashInit(&amp;hashctx);\n\n  bytes = 0;\n  characters = 0;\n\n#ifdef DEBUG49\n  fprintf(stdout, \"SSL_read()\\n\");\n#endif\n  int bytesneeded = 0, bytesheader = 0, bytescontent = 0;\n  \n  do {\n    cnt = SSL_read(ssl, buffer, sizeof(buffer));\n    if(cnt &lt; 0) {\n      int err, err2;\n      err = SSL_get_error(ssl, cnt);\n      err2 = ERR_get_error();\n\n      fprintf(stderr, \"\\n%s: cannot SSL_read()\", procname);\n      fprintf(stderr, \", retval: %d\", cnt);\n      fprintf(stderr, \", errno: %d\", errno);\n      fprintf(stderr,\", SSL_get_error() %d\", err);\n      fprintf(stderr,\", ERR_get_error() %d\\n\", err2);\n      perror(\"SSL_read\");\n      fflush(stderr);\n      break;\n    }\n\n#ifdef DEBUG50\n    write(1, buffer, cnt);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes += cnt;\n\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n    if(bytesneeded == 0) {\n      char *p;\n      p = buffer;\n      int count = 0;\n      while(*p != '\\0') {\n\tif(!strncmp(p, \"\\r\\nContent-Length: \", 18)) {\n\t  bytescontent = atoi(p + 18);\n\t}\n\tif(!strncmp(p, \"\\r\\n\\r\\n\", 4)) {\n\t  bytesheader = count;\n\t}\n\tp++;\n\tcount++;\n      }\n      bytesneeded = bytescontent + bytesheader + 4;\n    }\n  } while(SSL_pending(ssl) || bytes &lt; bytesneeded);\n\n  if(verbose) {\n    fprintf(stdout,\"\\nbytescontent:%d\", bytescontent);\n    fprintf(stdout,\", bytesheader:%d\", bytesheader);\n    fprintf(stdout,\", bytesneeded:%d\", bytesneeded);\n    fflush(stdout);\n  }\n#ifdef OLD1\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_read()\\n\");\n#endif \n  while((cnt = SSL_read(ssl, buffer, sizeof(buffer))) &gt; 0) {\n#ifdef DEBUG49\n    fprintf(stdout,\"SSL_read() round\\n\");\n#endif \n    \n#ifdef DEBUG50\n    write(1, buffer, cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes += cnt;\n    for(c = 0; c &lt; cnt; c++) {\n      if(buffer&#91;c] &lt; 0x80 || buffer&#91;c] &gt; 0xbf)\n\tcharacters++;\n    }\n  }\n  fflush(stdout);\n  if(cnt &lt; 0) {\n    fprintf(stderr, \"\\n%s: SSL_read()\", procname);\n    fprintf(stderr, \", status: %d\", status);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_read\");\n    fflush(stderr);\n  }\n  \n#endif\n  \n  fflush(stdout);\n\n  hash_update_cvar(&amp;hashctx);\n  HashFinal(hash, &amp;hashctx);\n\n  if(verbose) {\n    fprintf(stdout,\"\\n, %d bytes read\", bytes);\n    fprintf(stdout,\", %d characters read\", characters);\n    fprintf(stdout,\", sha256: \");\n    for(int c = 0;c &lt; HashLen; c++) {\n      fprintf(stdout,\"%02x\", hash&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n    newressu_output = 0; \n }\n#ifdef NOTUSED\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_shutdown()\\n\");\n#endif \n  SSL_shutdown(ssl);\n#endif\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_free()\\n\");\n#endif \n  SSL_free(ssl);\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_free()\\n\");\n#endif \n  SSL_CTX_free(ctx);\n  close(s);\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n \u00a9. Maailman parhaat satunnaisbitit: https:\/\/moijari.com:5006. Suomessa lahjoituksen voi tehd\u00e4, mutta sit\u00e4 ei voi pyyt\u00e4\u00e4. Jos haluat lahjoittaa kuitenkin projektille, laita lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Jos lahjoitat sata euroa tai enemm\u00e4n ja haluat vastalahjan, saat vastalahjana sudokun. Vastalahjasudokua&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=1874\">Continue reading <span class=\"screen-reader-text\">Newressu(4.10): in search for randomness. reduced sha256 calls in stream cipher (stream_bytes), rewrote pseudoressu_bytes(), sudokues everywhere, new look at database db8, query utility to debug db8, added switch (&#8211;query) to newressusudoku to use db8 query, added more function to db8 query, added sudokuid to sudoku record, added semaphores as sudokuid locking<\/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,5],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1874"}],"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=1874"}],"version-history":[{"count":645,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1874\/revisions"}],"predecessor-version":[{"id":2944,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1874\/revisions\/2944"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}