Back to terttu 2: Thoughts, Finally server stays up 2: even better… Intermission there will be ressu3… last version of newressu.c published, winter sudokues published

Kaikki oikeudet pidätetään ©. Jos haluat tukea projektia (osallistua palvelinkustannuksiin, tarjota koodausvissyn tai tulevaisuudessa maksaa palkkaa), laita muutaman euron lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikenttään nimesi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi.

Tässä postissa uutena kuvat, seuraava on tietenkin kuninkaanportti, Suomenlinna. Kuvat ovat aina omiani. Muutkin kuvat tässä postissa paitsi talvikuva ovat kuninkaanportin läheisyydestä. Olen yrittänyt valita kuvat niin, ettei niissä ole ketään, varsinkaan lapsia..

Tuo edellisissä posteissa tehty palvelin (https://moijari.com:5008/) on pysynyt hyvin pystyssä.

Jos etsit kesäsudokuja, artikkelissa (https://moijari.com/?p=2930) löytyy niitä.

Lisää sudokuja: (https://moijari.com/?p=3372), Experimental: (https://moijari.com/?p=3344), Vol1: (https://moijari.com/?p=3331), Vol2, Vol3, Vol4: (https://moijari.com/?p=3336) ja Vol 5: (https://moijari.com/?p=3372).

Jos haluat tehdä ensimmäiset talvisudokut, ne ovat tässä. Ensimmäiset sudokut ovat helpompia, ja ne vaikeutuvat mentäessä eteenpäin (clues pienenee), samoin jos rounds (ro) on suurempi, sudokun pitäisi olla vaikeampi: (vaikeimmissa kannattaa kokeilla snyder merkintöjä. Noissa experimental sudokuissa on vielä steps (st), joka kasvaa vaikeammissa sudokuissa)

    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           | 4       9 | 5   6     |
B |     7   6 | 5         | 9   1   4 |
C | 5       4 | 6       2 | 3   8   7 |
  +-----------+-----------+-----------+
D | 1   5     |           | 4         |
E |     3     |           | 1   2   6 |
F |         9 |         3 |           |
  +-----------+-----------+-----------+
G | 9   8   2 | 7   5   4 |     3   1 |
H |         5 | 3       1 | 2   4   9 |
I |     4     |         6 | 8   7   5 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:45
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 9   2     |         7 | 4       6 |
B | 7   5   4 | 3   6     | 2       8 |
C | 1       8 |           |           |
  +-----------+-----------+-----------+
D | 2       6 |           |     4   9 |
E | 3         | 7   2     | 1   8     |
F | 5   7   1 | 4   9   8 |         2 |
  +-----------+-----------+-----------+
G | 8         |     5   4 | 9         |
H | 4   9   7 | 2   8     |           |
I | 6   1   5 |     7     |     2     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:44
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 6       5 | 9   1     |         4 |
B |         2 |     7     |           |
C | 9   8     |         3 | 7   6   1 |
  +-----------+-----------+-----------+
D | 4       7 | 8   2     | 1       3 |
E | 3   1   6 | 5         |     4     |
F | 2   9   8 |           |           |
  +-----------+-----------+-----------+
G | 7   4   3 |           | 8       2 |
H | 8   2   9 | 7   3   5 | 4   1     |
I | 5       1 |     8     |           |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:43
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 6   9     |     2   5 | 7   8   1 |
B | 2       4 |     8     |     6     |
C | 8   1     |         7 |     2   3 |
  +-----------+-----------+-----------+
D | 1         |           | 2   3     |
E | 5   6   7 | 2       9 | 1         |
F | 3       2 |           |           |
  +-----------+-----------+-----------+
G |     5   6 | 7       3 |           |
H | 4         |     9   8 | 3   7   6 |
I | 7         |     1   2 | 5       4 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:42
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 5   3   7 | 8   1     | 4   6     |
B |         2 | 5       4 |         7 |
C | 4         |           | 1   5   9 |
  +-----------+-----------+-----------+
D |     2   9 | 6         |     4     |
E | 6   7   4 | 9   2   1 | 8   3     |
F |         5 | 4         |     2   6 |
  +-----------+-----------+-----------+
G |     6   8 |           |           |
H | 9       3 | 2   7   8 |         4 |
I |           | 3         |     7     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:41
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           |         9 | 8   1   4 |
B |     1     |           | 5       3 |
C | 9   5   4 | 1   8   3 |     6   2 |
  +-----------+-----------+-----------+
D | 3   7   8 |         4 | 6       1 |
E | 4         |           | 3   2   7 |
F | 1         |     3   7 | 9         |
  +-----------+-----------+-----------+
G |         3 | 6         | 2         |
H | 7       9 | 3   2     |           |
I |     2     |     7   8 | 4         |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:40
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |         2 | 5   3     |           |
B |         8 |     1   7 | 3   2   9 |
C |     6   7 |         4 |     1     |
  +-----------+-----------+-----------+
D |           |     2     | 5         |
E |         4 |     6     |     3   1 |
F | 8   9     | 7   5     | 4         |
  +-----------+-----------+-----------+
G | 1   7   5 | 9   8   6 | 2   4   3 |
H | 6   2   3 |         5 |           |
I | 4         |         2 |           |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:39
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |         1 |           | 5   7   4 |
B | 8   4   7 | 1   5   9 | 6       3 |
C |     2     | 7         | 8   9   1 |
  +-----------+-----------+-----------+
D | 3   7   9 | 6         |           |
E |           | 3         |           |
F |     5     |     7     |         6 |
  +-----------+-----------+-----------+
G |     9     | 4       6 |     5   2 |
H | 2         | 5         | 7   3   8 |
I | 1   8     |           |         9 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:38
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 3         | 5         |         4 |
B | 4   5     |           | 6       1 |
C |     8     |         9 |         5 |
  +-----------+-----------+-----------+
D | 7       1 | 4       8 |         3 |
E | 5   2   8 |           |     4   7 |
F |     4   3 |     5   7 | 2   1   8 |
  +-----------+-----------+-----------+
G |     6   4 |     1     |           |
H |     1     |           | 4   3   2 |
I | 9         |           | 1   8     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:37
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 9   1   6 |     4     |     5     |
B |           |           |     8   6 |
C |     7     | 2         |     4     |
  +-----------+-----------+-----------+
D |     9     |     8     |     7     |
E | 3   4     |         2 |           |
F |     5     |         7 | 2   6     |
  +-----------+-----------+-----------+
G | 7   6   5 |         8 | 1   3   4 |
H | 2   3     | 7       4 | 8   9   5 |
I |     8     |           |     2     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:36
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 8         |           |     1     |
B |     9     |     3   1 | 7         |
C |           | 5       6 |         3 |
  +-----------+-----------+-----------+
D | 1       2 | 4   8   3 |         6 |
E |         6 |         9 |           |
F | 5   8     |         7 | 2         |
  +-----------+-----------+-----------+
G |     2   8 | 9         | 3         |
H |     6   1 |     7   2 |     8   5 |
I | 3         |     6     | 9   2     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:2 clues:35
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 5   3     |     9   2 |           |
B | 1         | 8   7     |     5     |
C |     2     |     1     |           |
  +-----------+-----------+-----------+
D |           |           | 4         |
E |         5 | 7   4     | 6         |
F |     7     |         9 |     2     |
  +-----------+-----------+-----------+
G | 4         | 2   8   1 |         6 |
H |     6     | 4   3   5 |         2 |
I |     8   2 | 9   6     | 5   4     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:34
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 5         |         4 |     2   7 |
B |         6 | 9       7 | 4       1 |
C |     4     |           | 5   8     |
  +-----------+-----------+-----------+
D |           |         1 |           |
E | 1         | 4   8   2 |     6   5 |
F | 9   2     |     3     | 7         |
  +-----------+-----------+-----------+
G | 4   7     | 2       9 |           |
H |           | 3   7     | 8         |
I |     5     |     4   8 |           |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:33
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 6         |     3     |     1   2 |
B |           |           |     3     |
C |     5   1 | 8         | 7       4 |
  +-----------+-----------+-----------+
D | 2   9   3 |     8   4 |           |
E | 5   8     |           |     2     |
F |     7   6 | 3   9     | 4         |
  +-----------+-----------+-----------+
G | 4         |           |         9 |
H | 9   3     | 2         |         1 |
I |         5 |           | 2   8     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:32
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 5         |         6 |     1   7 |
B |         3 | 8   5   1 |     4     |
C |           |           |           |
  +-----------+-----------+-----------+
D | 9         |           |         8 |
E |         8 |         3 |           |
F | 1   5     |           | 2       4 |
  +-----------+-----------+-----------+
G |     8     | 1   4   9 | 3       6 |
H | 3   7     |         8 |     2   1 |
I | 6         |     7   2 |           |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:31
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           | 6         |         4 |
B | 7       9 |         4 | 8   2     |
C | 4         |         2 | 5       7 |
  +-----------+-----------+-----------+
D |           |           | 6       5 |
E |     3     | 8       7 |     9     |
F |           |         6 |     7     |
  +-----------+-----------+-----------+
G | 6   1     |         5 | 3         |
H | 2       8 | 4         | 7         |
I | 3         |         1 |     4     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:4 clues:30
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           |     8   9 |           |
B |           | 4   2     |           |
C |           | 5         |         3 |
  +-----------+-----------+-----------+
D |           | 3       4 | 1       8 |
E | 5         | 6   9     |     2     |
F | 7         |           |         9 |
  +-----------+-----------+-----------+
G | 2       1 |           |         5 |
H | 3       7 |     5   6 | 4         |
I | 4   9   5 | 8         |     7     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:4 clues:29
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 7         | 1         | 9       5 |
B |           |     4     |     8   1 |
C |     4     |           |           |
  +-----------+-----------+-----------+
D |     1     | 3   7   9 |     6     |
E | 8       9 | 4         |           |
F |         6 | 5   8     | 2         |
  +-----------+-----------+-----------+
G |     3     |           |         6 |
H |           | 2         |           |
I | 4   8   5 |     9     | 3         |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:3 clues:28
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 5         |         6 | 1         |
B | 8   4     |           |     6     |
C |           | 4       2 | 8       3 |
  +-----------+-----------+-----------+
D | 3         |           |           |
E | 7   2   8 |           |           |
F | 6       1 | 2   5     |           |
  +-----------+-----------+-----------+
G |           | 9         | 3   7     |
H |     7   9 |     4     |         8 |
I |           |     1     |         4 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:4 clues:27
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |         6 |         5 |     9     |
B |     9     |     1   4 | 7         |
C |     8     |     7     | 1         |
  +-----------+-----------+-----------+
D | 3   2     |     6     |           |
E | 7         |     2     |     4     |
F |     6   8 |         1 |     2     |
  +-----------+-----------+-----------+
G |           |           |     3   4 |
H |           |         7 | 5         |
I |           | 3         |     6     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:6 clues:26
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           |     4     | 5         |
B | 2         |     1     |         8 |
C |           |         8 |     6   3 |
  +-----------+-----------+-----------+
D | 7   6     |         5 | 9         |
E | 4         |           |           |
F |         2 |           |         4 |
  +-----------+-----------+-----------+
G | 8   4     |           |         7 |
H |     2   5 | 9         |     3     |
I |           | 3   6     | 8         |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:7 clues:25
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           | 8       1 |           |
B |         5 |         3 |     6     |
C |           |         9 | 7       5 |
  +-----------+-----------+-----------+
D |           |     1     | 2         |
E |         1 |           |           |
F | 9       3 | 4   7     |           |
  +-----------+-----------+-----------+
G | 2         |           | 5       6 |
H |         4 | 6         |         3 |
I |           | 3   8     |         4 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:4 clues:24
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           | 5       4 | 9   8     |
B |         7 |     2     |           |
C |     6     |         1 |           |
  +-----------+-----------+-----------+
D |           | 3         | 6   4     |
E |     2     |           |           |
F | 7         |         9 |           |
  +-----------+-----------+-----------+
G |           | 8         | 2       9 |
H |         3 |           |     6     |
I | 8         | 1         | 7       5 |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:7 clues:23
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           |         9 |           |
B |           | 8         | 5       3 |
C |           |         6 |         7 |
  +-----------+-----------+-----------+
D | 7         |           | 8         |
E |           |         5 |         6 |
F | 1         | 4   9   3 |           |
  +-----------+-----------+-----------+
G |         3 | 5         |     6     |
H |     8   4 |           | 2         |
I | 9         | 3         |           |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:5 clues:22
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |     2     |     3     | 5   4     |
B |         9 |     2     |           |
C | 6         |           | 7         |
  +-----------+-----------+-----------+
D | 5   3   1 |           |     6     |
E |           | 8       7 |           |
F |           |           | 1         |
  +-----------+-----------+-----------+
G |     7     |           | 6         |
H | 8   1     |     4     |           |
I |           |           |     9     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:6 clues:21
    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A | 9         |     8     |           |
B |         7 |           |     3     |
C | 2       6 | 1   9     |           |
  +-----------+-----------+-----------+
D |           |     5     |           |
E |     3     |     6     |           |
F | 8         |           | 4   2     |
  +-----------+-----------+-----------+
G |     7     |           |           |
H |     6     |           |         9 |
I |         4 |         5 | 1         |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:6 clues:20

Täältä löytyvät ensimmäiset joulusudokut (https://moijari.com/?p=3277).

Sitten artikkelin varsinaiseen asiaan:

Palvelin tulostaa seuraavankaltaisen sivun:

Hello world!

Tämä on artikkelin https://moijari.com?p=2990 testiohjelma.

Ohjelma löytyy tästä linkistä https://moijari.com:5008. Muutin myös html-versiota palvelimesta, se löytyy linkistä https://moijari.com:5009. Tee minulle palvelus ja painele näitä hetki, niin saan tarkistettua että ne toimivat oikein.

Seuraava kappale sisältää ressun tekemiä satunnaisbittejä. Ne ovat tässä vain tilan täytteeksi.
00000 815351217487910435669192172422951946696212529
00001 920813973742415362649994596558010088465040675
00002 240957540572627626019678885898823975217177955
00003 588737120498722070263736259491307364795007018
00004 099088516044714427477581177561019219994794028
00005 671836924618350610422165035986981986642212559
00006 903624466108326292581456051717969002015996523
00007 174214962253101545608670175806344579522732446
00008 582106588595739282558149472893211536930107155
00009 065077579202041683237466269212366696651544942

DBS3 version 0.15 ©, sha256(fb51c52020f4658aea34fa92a464228702888f91f21a688b72e72b6b5a9db329)

ja tulostaa seuraavankaltaisen html:n:

<!doctype html>
<html lang="fi">
	<head>
		<meta charset="utf-8">
		<title>dbs3</title>
		<meta name="author" content="Jari Kuivaniemi">
		<meta name="copyright" content="Jari Kuivaniemi">
		<meta name="format-detection" content="telephone=no">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
	</head>
	<body>
		<h1>Hello world!</h1>
		<p>Tämä on artikkelin
			<a href="https://moijari.com?p=2990">https://moijari.com?p=2990</a>
			testiohjelma.
		</p>
		<p>Ohjelma löytyy tästä linkistä
			<a href="https://moijari.com:5008">https://moijari.com:5008</a>. Muutin myös
			html-versiota palvelimesta, se löytyy linkistä
			<a href="https://moijari.com:5009">https://moijari.com:5009</a>. Tee minulle
			palvelus ja painele näitä hetki, niin saan tarkistettua että ne toimivat oikein.
		</p>
		<p>Seuraava kappale sisältää ressun tekemiä satunnaisbittejä. Ne ovat tässä vain tilan
		täytteeksi.</p>
		<code>00000 913172437725583125656813961989111569116651622<br>
			00001 668091985964193551241952738289133440806661184<br>
			00002 549190318300809959223119033099901889257655218<br>
			00003 216375827226876174409310032753849534437058619<br>
			00004 412828931075417056583548732955519735473364867<br>
			00005 778209799556888690223374723126772360482730235<br>
			00006 394862247871294866478215333972664754081371156<br>
			00007 437070499366697726219758787597618390377022999<br>
			00008 894827086752475366734695623137289506478059144<br>
			00009 611628644764270179833791103311275126306740678<br>
		</code>
		<p>DBS3 version 0.15 ©,
		sha256(fb51c52020f4658aea34fa92a464228702888f91f21a688b72e72b6b5a9db329)</p>
	</body>
</html>

Samoin ressusta on kehitin uuden version 2 “ressu2” eli tässä taas kerrataan alkuperäistä tavoitetta: palvelimen pitäisi oppia ymmärtämään seuraavanlaisia rivejä:

'memberid' = "customerid", 'memberapp' = "customerid"
'memberid' = "countryid", 'memberapp' = "countryid"
'memberid' = "productid", 'memberapp' = "productid"
'memberid' = "billid", 'memberapp' = "billid"
'appid' = "country", 'chapter' = "header", 'memberid' = "countryid"
'appid' = "country", 'chapter' = "header", 'memberid' = "countryname"
'countryid' = "fi", 'countryname' = "Finland"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyname"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyaddress"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyzip"
'appid' = "company", 'chapter' = "header", 'memberid' = "companycountry"
'appid' = "company", 'chapter' = "header", 'memberid' = "fiscalyear"
'appid' = "company", 'chapter' = "header", 'memberid' = "fiscalperiod"
'companyid' = "1", 'companyname' = "Vene Oy", 'companyaddress' = "venekatu 1", 'companyzip' = "00500", 'companycountry' = "fi", 'fiscalyear' = "2025", 'fiscalperiod' = "1"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customername"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customeraddress"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customerzip"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customercountry"
'customerid' = "1", 'customername' = "Asiakas 1", 'customeraddress' = "asiakaskatu 1", 'customerzip' = "00500", 'customercountry' = "fi"
'customerid' = "2", 'customername' = "Asiakas 2", 'customeraddress' = "asiakaskatu 2", 'customerzip' = "00500", 'customercountry' = "fi"
'customerid' = "3", 'customername' = "Asiakas 3", 'customeraddress' = "asiakaskatu 3", 'customerzip' = "00500", 'customercountry' = "fi"
'appid' = "product", 'chapter' = "header", 'memberid' = "productid"
'appid' = "product", 'chapter' = "header", 'memberid' = "productname"
'appid' = "product", 'chapter' = "header", 'memberid' = "productprice"
'productid' = "1", 'productname' = "Vene", 'productprice' = "100"
'productid' = "2", 'productname' = "Airot", 'productprice' = "10"
'productid' = "3", 'productname' = "Tappi", 'productprice' = "5"
'appid' = "bill", 'chapter' = "header", 'memberid' = "billid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "customername"
'appid' = "bill", 'chapter' = "header", 'memberid' = "total"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "billid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "billlineid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productname"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productprice"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "quantity"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "amount"
'billid' = "1", 'companyid' = "1", 'customerid' = "1", 'customername' = "Asiakas 1", 'total' = "115"
'billid' = "1", 'billlineid' = "1", 'productid' = "1", 'productname' = "Vene", 'productprice' = "100", 'quantity' = "1", 'amount' = "100"
'billid' = "1", 'billlineid' = "2", 'productid' = "1", 'productname' = "Airot", 'productprice' = "10", 'quantity' = "1", 'amount' = "10"
'billid' = "1", 'billlineid' = "3", 'productid' = "1", 'productname' = "Tappi", 'productprice' = "5", 'quantity' = "1", 'amount' = "5"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "transactionid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "customername"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "billid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "fiscalyear"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "fiscalperiod"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "transactionid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "transactionlineid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "productid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "productprice"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "quantity"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "amount"
'transactionid' = "1", 'companyid' = "1", 'customerid' = "1", 'customername' = "Asiakas 1", 'billid' = "1", 'fiscalyear' = "2025", 'fiscalperiod' = "1"
'transactionid' = "1", 'transactionlineid' = "1", 'productid' = "1", 'productprice' = "100", 'quantity' = "1", 'amount' = "100"
'transactionid' = "1", 'transactionlineid' = "2", 'productid' = "2", 'productprice' = "10", 'quantity' = "1", 'amount' = "10"
'transactionid' = "1", 'transactionlineid' = "3", 'productid' = "3", 'productprice' = "5", 'quantity' = "1", 'amount' = "5"

, palvelin kirjoittaa seuraavankaltaisen lokin:

20250830175147UTC starting dbs3 "DBS3 version 0.09 ©", port:5008, https
20250830175147UTC cert       xx xx xx xx...
20250830175147UTC private    xx xx xx xx...
20250830175147UTC server_https_init()
20250830175147UTC SSL_library_init()
20250830175147UTC OpenSSL_add_ssl_algorithms()
20250830175147UTC OpenSSL_add_ciphers()
20250830175147UTC OpenSSL_load_error_strings()
20250830175147UTC SSLv23_server_method()
20250830175147UTC SSL_CTX_new()
20250830175147UTC SSL_CTX_use_certificate_file()
20250830175147UTC SSL_CTX_use_PrivateKey_file()
20250830175147UTC cert       xx xx xx xx...
20250830175147UTC private    xx xx xx xx...
20250830175147UTC SSL_CTX_load_verify_locations()
20250830175147UTC server_basic_socket()
20250830175147UTC server_getaddrinfo()
20250830175147UTC getaddrinfo()
20250830175147UTC server_socket()
20250830175147UTC socket()
20250830175147UTC server_bind()
20250830175147UTC bind()
20250830175147UTC freeaddrinfo()
20250830175147UTC server_listen()
20250830175147UTC listen()
20250830175147UTC accept()
20250830175201UTC ========================================
20250830175201UTC dbs_time_vars()
20250830175201UTC fork start (parent) getpid:12334 getppid:1
20250830175201UTC fork()
20250830175201UTC fork end (parent) pid:12335 getpid:12334 getppid:1
20250830175201UTC server_close()
20250830175201UTC init_child()
20250830175201UTC close()
20250830175201UTC close(s)
20250830175201UTC cert       xx xx xx xx...
20250830175201UTC close(s)
20250830175201UTC private    xx xx xx xx...
20250830175201UTC https_client()
20250830175201UTC accept()
20250830175201UTC SSL_new()
20250830175201UTC SSL_set_fd()
20250830175201UTC SSL_accept()
20250830175201UTC SSL_get_peer_certificate(), No peer certificate
20250830175201UTC SSL_read()
20250830175201UTC ========================================
20250830175201UTC dbs_time_vars()
20250830175201UTC fork start (parent) getpid:12334 getppid:1
20250830175201UTC fork()
20250830175201UTC fork end (parent) pid:12336 getpid:12334 getppid:1
20250830175201UTC init_child()
20250830175201UTC server_close()
20250830175201UTC close(s)
20250830175201UTC close()
20250830175201UTC cert       xx xx xx xx...
20250830175201UTC close(s)
20250830175201UTC private    xx xx xx xx...
20250830175201UTC https_client()
20250830175201UTC accept()
20250830175201UTC SSL_new()
20250830175201UTC SSL_set_fd()
20250830175201UTC SSL_accept()
20250830175201UTC SSL_get_peer_certificate(), No peer certificate
20250830175201UTC SSL_read()
20250830175201UTC SSL_read(), retval 540, errno: 0, SSL_get_error(): 0, ERR_get_error(): 0
20250830175201UTC (540 bytes)
20250830175201UTC GET / HTTP/1.1
Host: moijari.com:5008
Sec-Fetch-Dest: document
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: https://moijari.com:5008/
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Accept-Language: en-GB,en;q=0.9
Priority: u=0, i
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=xx xx xx xx...
Connection: keep-alive

_registerTMCloneTable
20250830175201UTC 1 reads, received 540 chars, read 540 total bytes, input buffer size 2048 chars, data="
20250830175201UTC "
20250830175201UTC htmlmethod: "GET"
20250830175201UTC htmlpath: "/"
20250830175201UTC htmlversion: "HTTP/1.1"
20250830175201UTC htmlfilename: ""
20250830175201UTC htmlfileextension: ""
20250830175201UTC htmlhost: "moijari.com:5008"
20250830175201UTC htmluseragent: "Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1"
20250830175201UTC htmlcookie: "PHPSESSID=xx xx xx xx..."
20250830175201UTC enter dba_loop()
20250830175201UTC entering dba_loop()
20250830175201UTC fetching cookies
20250830175201UTC htmlsessionid: ""
20250830175201UTC htmlmode: ""
20250830175201UTC htmllanguage: ""
20250830175201UTC end fetching cookies
20250830175201UTC html prettyprinter
20250830175201UTC buffers1: 0:96 1:1423 2:0 3:0 4:116 5:0 6:0 7:0 8:0
20250830175201UTC buffers2: 0:96 1:0 2:0 3:0 4:0 5:0 6:0 7:1539 8:0
20250830175201UTC buffers3: 0:96 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:1624
20250830175201UTC html prettyprinter done.
20250830175201UTC exit dba_loop2()
20250830175201UTC entering dba_loop2()
20250830175201UTC exiting dba_loop2()
20250830175201UTC buffers(ssl): 0:196SSL_write()
20250830175201UTC  1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:1624SSL_write()
20250830175201UTC HTTP/1.0 200 OK
Location: 
Server: DBS3 version 0.09 ©
Date: Sat, 30 Aug 2025 17:52:01 GMT
Content-Length: 1624
SHA256: 14f9261ba8b2d0955cdcd88ce63cf1414837042ceeb56e99cbcd8f8b362a9f92



20250830175201UTC <!doctype html>
<html lang="fi">
	<head>
		<meta charset="utf-8">
		<title>dbs3</title>
		<meta name="author" content="Jari Kuivaniemi">
		<meta name="copyright" content="Jari Kuivaniemi">
		<meta name="format-detection" content="telephone=no">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
	</head>
	<body>
		<h1>Hello world!</h1>
		<p>Tämä on artikkelin
			<a href="https://moijari.com?p=2990">https://moijari.com?p=2990</a>
			testiohjelma. Ohjelma löytyy tästä linkistä
			<a href="https://moijari.com:5008">https://moijari.com:5008</a>.
		</p>
		<p>Seuraava kappale sisältää ressun tekemiä satunnaisbittejä. Ne ovat tässä vain tilan
		täytteeksi.</p>
		<code>00000 20616874070457590523126122132497421268944884802220810261826959568<br>
			00001 17192985807111595612468232713117700741936846802133961244101879900<br>
			00002 02407386257484414673907086023803598802701388309148448685736962425<br>
			00003 50279311953963128957788744672545836449370328271465324371081029118<br>
			00004 70458842796761884608024944157410778280148696721938596935963966256<br>
			00005 05578472692405139090352146280861261687819185840399999490749778727<br>
			00006 42059647448790835009224071147698545710269723898238144550191259729<br>
			00007 92523533467026772824174205506373861584249958499398660047182445533<br>
			00008 17388179513424995966929981520791349290757431604968432604126712314<br>
			00009 12602138335914743028665941174114691854493502124843486708760074618<br>
		</code>
		<p>DBS3 version 0.09 ©,
		sha256(0ff070a4dda2dc67e499d2eb5b5ddf1efce64863ad517fdf2509bdfb4955cd5b)</p>
	</body>
</html>
20250830175201UTC SSL connection using TLS_AES_128_GCM_SHA256
20250830175201UTC dbs_query_vars()
20250830175201UTC SSL_free()
20250830175201UTC critical_wait()
20250830175201UTC critical_post()
20250830175201UTC server_close(news)
20250830175201UTC close()
20250830175201UTC fork end (child) pid:0 getpid:12336 getppid:12334
20250830175201UTC exit_child()
20250830175201UTC unlink dbs3pid12336.log
20250830175201UTC ========================================

(ehdotin teille lukijani että lisäisitte tarvittavia tietoja siihen). Ajatus tässä ensimmäisessä versiossa oli määritellä maat (country), yritys (company), asiakas (customer), tuote (product), lasku(bill) ja liiketapahtuma (transaction).

Tämä oli tälläinen yksinkertaistettu malli, jossa syötetään lasku, keräillään sen perusteella (ei tilausta, toimitusta, keräilyä jne.). Samoin liiketapahtumat perustuivat yksinkertaiseen kirjanpitoon.

Ajatus on että näiden perusteella voin miettiä mitä toimintoja terttuun tarvitaan. (mietin myös pitäisikö tämä scripti (ja xml kirjoittaa ja luoda kannasta esimerkiksi seuraavilla määrityksillä, ja miksei myös tuloste)). Kun aikoinaan aloin miettiä tätä, mietin voisiko taulut rakentaa tähän(noin 1997-1998).

'memberid' = "customerid", 'memberapp' = "customerid"
'memberid' = "countryid", 'memberapp' = "countryid"
'memberid' = "productid", 'memberapp' = "productid"
'memberid' = "billid", 'memberapp' = "billid"
'appid' = "country", 'chapter' = "header", 'memberid' = "countryid"
'appid' = "country", 'chapter' = "header", 'memberid' = "countryname"
'countryid' = "fi", 'countryname' = "Finland"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyname"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyaddress"
'appid' = "company", 'chapter' = "header", 'memberid' = "companyzip"
'appid' = "company", 'chapter' = "header", 'memberid' = "companycountry"
'appid' = "company", 'chapter' = "header", 'memberid' = "fiscalyear"
'appid' = "company", 'chapter' = "header", 'memberid' = "fiscalperiod"
'companyid' = "1", 'companyname' = "Vene Oy", 'companyaddress' = "venekatu 1", 'companyzip' = "00500", 'companycountry' = "fi", 'fiscalyear' = "2025", 'fiscalperiod' = "1"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customername"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customeraddress"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customerzip"
'appid' = "customer", 'chapter' = "header", 'memberid' = "customercountry"
'customerid' = "1", 'customername' = "Asiakas 1", 'customeraddress' = "asiakaskatu 1", 'customerzip' = "00500", 'customercountry' = "fi"
'customerid' = "2", 'customername' = "Asiakas 2", 'customeraddress' = "asiakaskatu 2", 'customerzip' = "00500", 'customercountry' = "fi"
'customerid' = "3", 'customername' = "Asiakas 3", 'customeraddress' = "asiakaskatu 3", 'customerzip' = "00500", 'customercountry' = "fi"
'appid' = "product", 'chapter' = "header", 'memberid' = "productid"
'appid' = "product", 'chapter' = "header", 'memberid' = "productname"
'appid' = "product", 'chapter' = "header", 'memberid' = "productprice"
'productid' = "1", 'productname' = "Vene", 'productprice' = "100"
'productid' = "2", 'productname' = "Airot", 'productprice' = "10"
'productid' = "3", 'productname' = "Tappi", 'productprice' = "5"
'appid' = "bill", 'chapter' = "header", 'memberid' = "billid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "bill", 'chapter' = "header", 'memberid' = "customername"
'appid' = "bill", 'chapter' = "header", 'memberid' = "total"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "billid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "billlineid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productid"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productname"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "productprice"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "quantity"
'appid' = "bill", 'chapter' = "lines", 'memberid' = "amount"
'billid' = "1", 'companyid' = "1", 'customerid' = "1", 'customername' = "Asiakas 1", 'total' = "115"
'billid' = "1", 'billlineid' = "1", 'productid' = "1", 'productname' = "Vene", 'productprice' = "100", 'quantity' = "1", 'amount' = "100"
'billid' = "1", 'billlineid' = "2", 'productid' = "1", 'productname' = "Airot", 'productprice' = "10", 'quantity' = "1", 'amount' = "10"
'billid' = "1", 'billlineid' = "3", 'productid' = "1", 'productname' = "Tappi", 'productprice' = "5", 'quantity' = "1", 'amount' = "5"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "transactionid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "companyid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "customerid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "customername"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "billid"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "fiscalyear"
'appid' = "transaction", 'chapter' = "header", 'memberid' = "fiscalperiod"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "transactionid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "transactionlineid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "productid"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "productprice"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "quantity"
'appid' = "transactionline", 'chapter' = "lines", 'memberid' = "amount"
'transactionid' = "1", 'companyid' = "1", 'customerid' = "1", 'customername' = "Asiakas 1", 'billid' = "1", 'fiscalyear' = "2025", 'fiscalperiod' = "1"
'transactionid' = "1", 'transactionlineid' = "1", 'productid' = "1", 'productprice' = "100", 'quantity' = "1", 'amount' = "100"
'transactionid' = "1", 'transactionlineid' = "2", 'productid' = "2", 'productprice' = "10", 'quantity' = "1", 'amount' = "10"
'transactionid' = "1", 'transactionlineid' = "3", 'productid' = "3", 'productprice' = "5", 'quantity' = "1", 'amount' = "5"

Perustoimintoja varten tarvitsette ainakin salasanan

'uname' = "testi", 'password' = "testaus", 'language' = "en"

Myös edellisten postien MR8 tarvitsee logon:ia, vapaasti MR8 perustui välimuisteihin ja peräkkäistiedostoon.

(Kielistä: ’word’ ’sijapääte’, ’sana’, ’kieli’ ’language’, ’alphabet’, ’aakkoset’, ’compress’, ’pakkaus’. Muutamia ’integer’ ’tyyppejä’ ’long long’ ’ long’ ’int’ ’char’ ’merkki’ ’character’ ’öökkösetö’ ’ä’ ’ö’ ’å’ ’finnish’, ’swedish’ ’euro’ ’fim’ ’suomi’ (ja muita), nämä oikeaan järjestykseen… , tiivisteitä: ’number’ ’sha’ ’bits’ ’number’, ’des’. ”Architecture processor, arkkitehtuuri prosessori”, interface. Digit, Digits, ’number’, ’digits’, ’numero’, ’numerot’, ‘utf-8’).

Lisään seuraavaan valittuja rivejä (vapaasti, toivottavasti menee edes lähelle oikeata…)

’digits’ = ”0123456789" \
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
 "abcdefghijklmnopqrstuvwxyz";
’digits’ =
 "!\"#$%&'()*+,-./0123456789:;<=>?@" \
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
 "abcdefghijklmnopqrstuvwxyz{|}~";

// Finnish alphabet
// Swedish alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ" =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ" \
 "abcdefghijklmnopqrstuvwxyzåäö";

// Danish alphabet
// Norwegian alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" \
 "abcdefghijklmnopqrstuvwxyzæøå";

// Norwegian alphabet
// Danish alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" \
 "abcdefghijklmnopqrstuvwxyzæøå";

// Estonian alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY" \
 "abcdefghijklmnopqrsšzžtuvwõäöüxy";

// Lithuanian alphabet
digits =
 "AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ" \
 "aąbcčdeęėfghiįyjklmnoprsštuųūvzž";

//Latvian alphabet
digits =
 "AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ" \
 "aābcčdeēfgģhiījkķlļmnņoprsštuūvzž";

// French alphabet
// Great Britain alphabet
// United States alphabet
// Italian alphabet
// English alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
 "abcdefghijklmnopqrstuvwxyz";

// Deutsch alphabet
digits =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" \
 "abcdefghijklmnopqrstuvwxyzäöüß";

// Greek alphabet
digits =
 "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ" \
 "αβγδεζηθικλμνξοπρστυφχψω";

// Japan alphabet
digits =
 "ぁあぃいぅうぇえぉおかがきぎく"
 "ぐけげこごさざしじすずせぜそぞた"
 "だちぢっつづてでとどなにぬねのは"
 "ばぱひびぴふぶぷへべぺほぼぽまみ"
 "むめもゃやゅゆょよらりるれろゎわ"
 "ゐゑをんゔゕゖ" +
 ”゠ァアィイゥウェエォオカガキギク"
 "グケゲコゴサザシジスズセゼソゾタ"
 "ダチヂッツヅテデトドナニヌネノハ"
 "バパヒビピフブプヘベペホボポマミ"
 "ムメモャヤュユョヨラリルレロヮワ"
 "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ";

// Hiragana
// Jp1
digits =
   "ぁあぃいぅうぇえぉおかがきぎく"
 "ぐけげこごさざしじすずせぜそぞた"
 "だちぢっつづてでとどなにぬねのは"
 "ばぱひびぴふぶぷへべぺほぼぽまみ"
 "むめもゃやゅゆょよらりるれろゎわ"
 "ゐゑをんゔゕゖ";

// Katakana
// Jp2
digits =
 "゠ァアィイゥウェエォオカガキギク"
 "グケゲコゴサザシジスズセゼソゾタ"
 "ダチヂッツヅテデトドナニヌネノハ"
 "バパヒビピフブプヘベペホボポマミ"
 "ムメモャヤュユョヨラリルレロヮワ"
 "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ";

// Hindi alphabet
//unsigned char *signs = "ऀँंःऺऻ़ऽािीॉॊोौ्ॎ
digits =
 "ऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढण"
 "तथदधनऩपफबभमयरऱलळऴवशषसहऽॐक़ख़ग़ज़ड़"
 "ढ़फ़य़ॠॡ।॥०१२३४५६७८९॰ॱॲॳॴॵॶॷॸॹॺॻॼॽॾ"
 "ॿ"; // 97 characters

// Hebrew alphabet
// ֐־ֿ׀ׁׂ׃ׅׄ׆ׇ׈׉׊׋׌׍׎׏אבגדהוזחטיךכלםמןנסעףפץצקרשת׫׬׭׮ׯװױײ׳״׵׶׷׸׹׺׻׼׽׾׿
digits = "אבגדהוזחטיךכלםמןנסעףפץצקרשת";

// phoenician alphabet
// foinikialaiset aakkoset
// phoenician: 𐤀𐤁𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊𐤋𐤌𐤍𐤎𐤏𐤐𐤑𐤒𐤓𐤔𐤕𐤖𐤗𐤘𐤙𐤚𐤛𐤜𐤝𐤞𐤟”
digits = "𐤀𐤁𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊𐤋𐤌𐤍𐤎𐤏𐤐𐤑𐤒𐤓𐤔𐤕𐤖𐤗𐤘𐤙𐤚𐤛";

// Braille alphabet
digits = // 0x2800 - 0x2900
 "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
 "⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿"
 "⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿"
 "⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿";

// Gothic alphabet
digits =
 "𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷𐌸𐌹𐌺𐌻𐌼𐌽𐌾𐌿"
 "𐍀𐍁𐍂𐍃𐍄𐍅𐍆𐍇𐍈𐍉𐍊";

// Cards
digits =
 "🂡🂢🂣🂤🂥🂦🂧🂨🂩🂪🂫🂭🂮"
 "🂱🂲🂳🂴🂵🂶🂷🂸🂹🂺🂻🂽🂾"
 "🃁🃂🃃🃄🃅🃆🃇🃈🃉🃊🃋🃍🃎"
 "🃑🃒🃓🃔🃕🃖🃗🃘🃙🃚🃛🃝🃞";

// Cardsuits
digits =
 "♠♡♢♣♤♥♦♧";

// Chessmen
digits =
 "♔♕♖♗♘♙♚♛♜♝♞♟";

// Dice
digits =
 "⚀⚁⚂⚃⚄⚅";

// Mahjong
// removed 🀄 & 🀫
 "🀀🀁🀂🀃🀅🀆" \
 "🀇🀈🀉🀊🀋🀌🀍🀎🀏" \
 "🀐🀑🀒🀓🀔🀕🀖🀗🀘" \
 "🀙🀚🀛🀜🀝🀞🀟🀠🀡" \
 "🀢🀣🀤🀥🀦🀧🀨🀩🀪";

// Dna
 digits = ”acgt”

// DNA
  digits = ”ACGT”

// Million random digits
  digits =

// Party
  digits = ”🍾🥂”

Korean merkistö on kerrottu koodilla (cee):

digits = NULL;
digits_add_limits(&digits,0xac00,0xd7a3);   // Hangul Syllables (AC00–D7A3)
//digits_add_limits(&digits,0x1100,0x11ff); // Hangul Jamo (1100–11FF)
//digits_add_limits(&digits,0x3130,0x318f); // Hangul Compatibility Jamo (3130–318F)
//digits_add_limits(&digits,0xa960,0xa97f); // Hangul Jamo Extended-A (A960–A97F)
//digits_add_limits(&digits,0xd7b0,0xd7ff); // Hangul Jamo Extended-B (D7B0–D7FF)

Kiinalaisessa merkistössä on niin paljon merkkejä, että se on myös seuraavassa kerrottu koodilla:

// Chinese alphabet
// Jp3
// Japanese kanji alphabet
digits = NULL;
digits_add_limits(&digits, 0x4e00, 0x9fef);

Liput koostuvat merkeistä ’aa’, ’ab’ – ’zy’, ’zz’ : (peräkkäisissä ’positioissa’ olevat liput näkyvät oikean näköisinä. esimerkiksi liput ’cd’, ’mn’ ja ’gh’ ovat varattuja):

digits = "🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿";
//digits = "🇫🇮🇸🇪🇳🇴🇩🇰🇪🇪🇱🇻🇱🇹";

, liput jatkoa:

/*
🇦
🇧
🇨
🇩
🇪
🇫
🇬
🇭
🇮
🇯
🇰
🇱
🇲
🇳
🇴
🇵
🇶
🇷
🇸
🇹
🇺
🇻
🇼
🇽
🇾
🇿
*/
/*
  🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿
*/

Lippumerkit voivat olla vaikka seuraavassa rakenteessa (~tietueessa):

unsigned char *flagchars[] =
    { "🇦", "🇧", "🇨", "🇩", "🇪", "🇫", "🇬", "🇭", "🇮", "🇯",
      "🇰", "🇱", "🇲", "🇳", "🇴", "🇵", "🇶", "🇷", "🇸", "🇹",
      "🇺", "🇻", "🇼", "🇽", "🇾", "🇿" };

rakenne lippuja varten:

struct idflags { // 202307 JariK
  unsigned char *id;
  unsigned char *flags;
} idsflags[] = {
};

, täytettä lippurakenteeseen:

  { "🇫🇮", "🇫🇮: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND" },
  { "🇦🇽", "🇦🇽: ax, ala, Åland, aland, NORDIC, FINLAND" },
  { "🇸🇪", "🇸🇪: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇳🇴", "🇳🇴: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇫🇴", "🇫🇴: fo, fro, FaroeIslands, NORDIC, DENMARK" },
  { "🇮🇸", "🇮🇸: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇬🇱", "🇬🇱: gl, grl, Greenland, NORTHAMERICA, NORDIC, DENMARK" },
  { "🇪🇪", "🇪🇪: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇻", "🇱🇻: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇹", "🇱🇹: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇺🇦", "🇺🇦: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇱", "🇦🇱: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇩", "🇦🇩: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA" },

aiempi pätkä newressusta: (idea on että voi newressussa kirjoittaa komennon kuten “$ newressu — flags —fi —se”, jolloin fi ja se löydetään edellisestä rakenteesta..) noita rivin lopussa olevia sanoja kuten Finland, Europe ja jne voi myös käyttää —all kääntää kaikki liput väärinpäin, eli —fi —all arpoo kaikkia muita lippuja paitsi Suomen lippuja: (suomea siinä ei ole kielenä, eli ainakin näissä tarvitaan kääntäjää):

int newressu_toggleflag(unsigned char *flag)
{
  int c, ok;
 
  if(!strcmp(flag, "ALL")) {
    idsall = !idsall;
    for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
      flagids[c] = idsall;
    }
    flagidflags = 1; // display flags
    ok = 1; // one flag toggled
  } else {
    ok = 0;
    for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
      if(newressu_strstr(idsflags[c].flags, flag)!=NULL) {
        flagids[c] = !flagids[c];
        flagidflags = 1; // display flags
        ok = 1; // one flag toggled
      }
    }
  }
  return (ok)
}

Tässä vielä edellisen käyttämä newressu_strstr():

unsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)
{
  int nlen = strlen(needle);
  unsigned char *p = haystack;

  while(*p != '\0') {
    if(!strncmp(p, needle, nlen) &&
       ( isblank(*(p + nlen)) || ispunct(*(p + nlen)) || *(p + nlen) == '\0' ) && // character after string
       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) // character before string
      return(p);
    p++;
  }
  return(NULL);
}

Seuraava debukki tulostaa kaikki utf-8 merkit:

  if(utf8) {

    int xlines;
    printcolumns(6, 0x10, 0, 64, &xlines);
   
    int utf8output = 0;
    for(c = 0; c < 65535 * 4; c++) {
      //for(c = 0x2800; c < 0x2900; c++) { // braille
      unsigned char buffer10[10];
      if(c % 64 == 0) {
        if(c > 0) {
          fprintf(stdout,"\n");
          utf8output = 0;
        }
        fprintf(stdout,"%5x ", c);
        utf8output = 1;
      }
      if(c >= 0 && c < 32) {
        c += 31;
        fprintf(stdout, "%-32s", "--- control characters ---");
        utf8output = 1;
      } else if(c >= 128 && c < 256) {
        c += 31;
        fprintf(stdout, "%-32s", "--- utf8 characters ---");
        utf8output = 1;
      } else {
        codetoutf8(buffer10, c);
        fprintf(stdout,"%s", buffer10);
        utf8output = 1;
      }
    }
    if(utf8output)
      fprintf(stdout,"\n");
    fflush(stdout);

    return(0);
  }

Tässä edellisen printcolumns():

static long long lines = 10, plines = 0, ptotallines = 0;

void printcolumns(int offset, int base, int startwith, int columns, int *clines) // 2023 JariK
{
  //---------11111111112222222222333333333344444444445555555555666666666677
  //12345678901234567890123456789012345678901234567890123456789012345678901
  //=======================================================================
  //00000 86747100388687087416829400778878989202760594993130062980826178851
  //00001 36862623069143814543525935285460059703805218323534266522497684582

  int c, d, digit, nonzero;
  unsigned char digits[0x10] = "0123456789abcdef";

  *clines = 0;

  if(base == 2)
    c = 1 << 12;
  else if(base == 8)
    c = 01000000;
  else if(base == 10)
    c = 1000000;
  else if(base == 16)
    c = 0x1000000;
  else {
    fprintf(stdout,"%s: printcolumns():", procname);
    fprintf(stdout," illegal base %d", base);
    fprintf(stdout,"\n");
    exit(1);
  }

  for(;c >= 1; c /= base) { // lines, 100000's, 10000's, 1000's ... 1's
    if(c >= columns)
      continue;

    for(d = 0; d < offset; d++)
      fprintf(stdout," "); // spaces in beginning of row

    nonzero = 0;
   
    for(d = startwith; d < columns + startwith; d++) { // column numbers
      digit = (d / c) % base;
      if(digit != 0)
        nonzero = 1;
      if(nonzero || c == 1)
        fprintf(stdout,"%c", digits[digit]); // nonzero digits after first nonzero
      else
        fprintf(stdout,"-"); // zeroes in beginning of row
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  if(pwords > 0) {
    if(slineno) {
      for(c = 0; c <= plinesdigits; c++) // +1
        fprintf(stdout,"-");
    }
    for(cwords = 0; cwords < pwords; cwords++) {
      print_spaces('-');
      fprintf(stdout,"w");
      if(charwidth == 2)
        fprintf(stdout,"-");
      for(c = 0; c < size - 1; c++) {
        fprintf(stdout,"-");
        if(charwidth == 2)
          fprintf(stdout,"-");
      }
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  for(d = 0; d < offset; d++)
    fprintf(stdout," "); // spaces in beginning of row
  for(d = startwith; d < columns + startwith; d++)
    fprintf(stdout,"=");
  fprintf(stdout,"\n");
  (*clines)++;
}

Tässä edellisen codetoutf8() rutiini:

static void codetoutf8(unsigned char *buf2, unsigned long long code)
{
  unsigned char *buf;

  buf = buf2;
  if(code <= 0x7f) {
    *buf++ = code;
  } else if(code <= 0x7ff) {            // 110xxxxx 10xxxxxx
    *buf++ = (0xc0 | ((code >> 6) & 0x1f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0xffff) {           // 1110xxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xe0 | ((code >> 12) & 0x0f));
    *buf++ = (0x80 | ((code >> 6) & 0x3f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0x10ffff) {         // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xf0 | ((code >> 18) & 0x07));
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffff) {        // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xf8 | ((code >> 24) & 0x03));
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x7fffffff) {       // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfc | ((code >> 30) & 0x01));
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0xfffffffff) {      // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfe);
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffffffff) {    // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xff);
    *buf++ = (0x80 | ((code >> 36) & 0x3f));      
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  }
  *buf = '\0';

#ifdef DEBUG42
  int c, print;

  fprintf(stdout,"codepoint: %lx", code);

  fprintf(stdout,", bin:");

  print = 0;
  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
    int bit = (code >> c) & 1;
    if(bit != 0)
      print = 1;
    if(print) {
      fprintf(stdout,"%d", bit);
      if(c > 0 && c % 8 == 0)
        fprintf(stdout,"|");
    }
  }

  fprintf(stdout,", oct:");
  print = 0;
  fprintf(stdout,"%lo", code);

  fprintf(stdout,", utf8: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout,"%02x", buf2[c]);
  }

  fprintf(stdout,", bin: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    if(c > 0)
      fprintf(stdout,"|");
    for(int d = 7; d >= 0; d--) {
      fprintf(stdout,"%d", buf2[c] >> d & 1);
    }
  }

  fprintf(stdout,", oct:");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout," %3o", buf2[c]);
  }
 
  fprintf(stdout,", character: %s", buf2);
  fprintf(stdout,"\n");
#endif
}

(Edellinen takaperin) ristiintarkistusta varten:

#define aDEBUG43 2

static void utf8tocode(unsigned long *code, unsigned char *buf2)
{
  unsigned char *buf;
  
  *code = 0;
  buf = buf2;
  
  if(*buf <= 0x7f) {                  // 0xxxxxxx
    *code = *buf;
  } else if(*buf < 0xc0) {            // 110xxxxx 10xxxxxx
    *code = 0;
  } else if(*buf < 0xe0) {            // 110xxxxx 10xxxxxx
    *code = *buf++ & 0x1f;
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xf0) {            // 1110xxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x0f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf<0xf8) {            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x07;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfc) {            // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x03;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfe) {            // 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x01;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xff) {            // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf == 0xff) {            // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  }
#ifdef DEBUG43
  int c;

  fprintf(stdout, "character: %s", buf2);

  fprintf(stdout, ", utf8: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout,"%02x", buf2[c]);
  }

  fprintf(stdout, ", bin: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    if(c > 0)
      fprintf(stdout, "|");
    for(int d = 7; d >= 0; d--)
      fprintf(stdout, "%d", buf2[c] >> d & 1);
  }

  fprintf(stdout, ", oct:");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout, " %3o", buf2[c]);
  }
  
  fprintf(stdout, ", codepoint: %lx", *code);
  fprintf(stdout, ", bin:");
  int print = 0;
  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
    int bit = (*code >> c) & 1;
    if(bit != 0)
      print = 1;
    if(print) {
      fprintf(stdout, "%d", bit);
      if(c > 0 && c % 8 == 0)
	fprintf(stdout, "|");
    }
  }

  fprintf(stdout, ", oct:");
  fprintf(stdout, "%lo", *code);
  
  fprintf(stdout, "\n");
#endif
}

Ristiintarkistava sorsa (ristiintarkistus vielä hakusessa):

Tässä edellisen tuloste:

      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
    0 --- control characters ---       !"#$%&'()*+,-./0123456789:;<=>?
   40 @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
   80 --- utf8 characters ---         --- utf8 characters ---        
   c0 --- utf8 characters ---         --- utf8 characters ---        
  100 ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿ
  140 ŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ
  180 ƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿ
  1c0 ǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿ
  200 ȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿ

Tässä joukko myöhempiä emojeja:

🌻🌼🌽🌾🌿
1f340 🍀🍁🍂🍃🍄🍅🍆🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍔🍕🍖🍗🍘🍙🍚🍛🍜🍝🍞🍟🍠🍡🍢🍣🍤🍥🍦🍧🍨🍩🍪🍫🍬🍭🍮🍯🍰🍱🍲🍳🍴🍵🍶🍷🍸🍹🍺🍻🍼🍽🍾🍿
1f380 🎀🎁🎂🎃🎄🎅🎆🎇🎈🎉🎊🎋🎌🎍🎎🎏🎐🎑🎒🎓🎔🎕🎖🎗🎘🎙🎚🎛🎜🎝🎞🎟🎠🎡🎢🎣🎤🎥🎦🎧🎨🎩🎪🎫🎬🎭🎮🎯🎰🎱🎲🎳🎴🎵🎶🎷🎸🎹🎺🎻🎼🎽🎾🎿
1f3c0 🏀🏁🏂🏃🏄🏅🏆🏇🏈🏉🏊🏋🏌🏍🏎🏏🏐🏑🏒🏓🏔🏕🏖🏗🏘🏙🏚🏛🏜🏝🏞🏟🏠🏡🏢🏣🏤🏥🏦🏧🏨🏩🏪🏫🏬🏭🏮🏯🏰🏱🏲🏳🏴🏵🏶🏷🏸🏹🏺🏻🏼🏽🏾🏿
1f400 🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿
1f440 👀👁👂👃👄👅👆👇👈👉👊👋👌👍👎👏👐👑👒👓👔👕👖👗👘👙👚👛👜👝👞👟👠👡👢👣👤👥👦👧👨👩👪👫👬👭👮👯👰👱👲👳👴👵👶👷👸👹👺👻👼👽👾👿
1f480 💀💁💂💃💄💅💆💇💈💉💊💋💌💍💎💏💐💑💒💓💔💕💖💗💘💙💚💛💜💝💞💟💠💡💢💣💤💥💦💧💨💩💪💫💬💭💮💯💰💱💲💳💴💵💶💷💸💹💺💻💼💽💾💿
1f4c0 📀📁📂📃📄📅📆📇📈📉📊📋📌📍📎📏📐📑📒📓📔📕📖📗📘📙📚📛📜📝📞📟📠📡📢📣📤📥📦📧📨📩📪📫📬📭📮📯📰📱📲📳📴📵📶📷📸📹📺📻📼📽📾📿
1f500 🔀🔁🔂🔃🔄🔅🔆🔇🔈🔉🔊🔋🔌🔍🔎🔏🔐🔑🔒🔓🔔🔕🔖🔗🔘🔙🔚🔛🔜🔝🔞🔟🔠🔡🔢🔣🔤🔥🔦🔧🔨🔩🔪🔫🔬🔭🔮🔯🔰🔱🔲🔳🔴🔵🔶🔷🔸🔹🔺🔻🔼🔽🔾🔿
1f540 🕀🕁🕂🕃🕄🕅🕆🕇🕈🕉🕊🕋🕌🕍🕎🕏🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧🕨🕩🕪🕫🕬🕭🕮🕯🕰🕱🕲🕳🕴🕵🕶🕷🕸🕹🕺🕻🕼🕽🕾🕿
1f580 🖀🖁🖂🖃🖄🖅🖆🖇🖈🖉🖊🖋🖌🖍🖎🖏🖐🖑🖒🖓🖔🖕🖖🖗🖘🖙🖚🖛🖜🖝🖞🖟🖠🖡🖢🖣🖤🖥🖦🖧🖨🖩🖪🖫🖬🖭🖮🖯🖰🖱🖲🖳🖴🖵🖶🖷🖸🖹🖺🖻🖼🖽🖾🖿
1f5c0 🗀🗁🗂🗃🗄🗅🗆🗇🗈🗉🗊🗋🗌🗍🗎🗏🗐🗑🗒🗓🗔🗕🗖🗗🗘🗙🗚🗛🗜🗝🗞🗟🗠🗡🗢🗣🗤🗥🗦🗧🗨🗩🗪🗫🗬🗭🗮🗯🗰🗱🗲🗳🗴🗵🗶🗷🗸🗹🗺🗻🗼🗽🗾🗿
1f600 😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮😯😰😱😲😳😴😵😶😷😸😹😺😻😼😽😾😿
1f640 🙀🙁🙂🙃🙄🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏🙐🙑🙒🙓🙔🙕🙖🙗🙘🙙🙚🙛🙜🙝🙞🙟🙠🙡🙢🙣🙤🙥🙦🙧🙨🙩🙪🙫🙬🙭🙮🙯🙰🙱🙲🙳🙴🙵🙶🙷🙸🙹🙺🙻🙼🙽🙾🙿
1f680 🚀🚁🚂🚃🚄🚅🚆🚇🚈🚉🚊🚋🚌🚍🚎🚏🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛🚜🚝🚞🚟🚠🚡🚢🚣🚤🚥🚦🚧🚨🚩🚪🚫🚬🚭🚮🚯🚰🚱🚲🚳🚴🚵🚶🚷🚸🚹🚺🚻🚼🚽🚾🚿

Muita emojeja (parilla ensimmäisellä rivillä voi olla sotkua… (Cyrillic), ne tulevat myöhemmin dumpissa uudelleen..):

  400 πρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ
  440 рстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿ
  480 Ҁҁ҂ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿ
  4c0 ӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӏӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹӺӻӼӽӾӿ
  500 ԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԐԑԒԓԔԕԖԗԘԙԚԛԜԝԞԟԠԡԢԣԤԥԦԧԨԩԪԫԬԭԮԯ԰ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿ
  540 ՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖ՗՘ՙ՚՛՜՝՞՟ՠաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտ
  580 րցւփքօֆևֈ։֊֋֌֍֎֏֐־ֿ
  5c0 ׀ׁׂ׃ׅׄ׆ׇ׈׉׊׋׌׍׎׏אבגדהוזחטיךכלםמןנסעףפץצקרשת׫׬׭׮ׯװױײ׳״׵׶׷׸׹׺׻׼׽׾׿
  340 ͰͱͲͳʹ͵Ͷͷ͸͹ͺͻͼͽ;Ϳ
  380 ΀΁΂΃΄΅Ά·ΈΉΊ΋Ό΍ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξο
  3c0 πρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿ
  400 ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп
  440 рстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿ
  480 Ҁҁ҂ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿ
  4c0 ӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӏӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹӺӻӼӽӾӿ
  600 ؀؁؂؃؄؅؆؇؈؉؊؋،؍؎؏؛؜؝؞؟ؠءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿ
𒒹𒒺𒒻𒒼𒒽𒒾𒒿
124c0 𒓀𒓁𒓂𒓃𒓄𒓅𒓆𒓇𒓈𒓉𒓊𒓋𒓌𒓍𒓎𒓏𒓐𒓑𒓒𒓓𒓔𒓕𒓖𒓗𒓘𒓙𒓚𒓛𒓜𒓝𒓞𒓟𒓠𒓡𒓢𒓣𒓤𒓥𒓦𒓧𒓨𒓩𒓪𒓫𒓬𒓭𒓮𒓯𒓰𒓱𒓲𒓳𒓴𒓵𒓶𒓷𒓸𒓹𒓺𒓻𒓼𒓽𒓾𒓿
12500 𒔀𒔁𒔂𒔃𒔄𒔅𒔆𒔇𒔈𒔉𒔊𒔋𒔌𒔍𒔎𒔏𒔐𒔑𒔒𒔓𒔔𒔕𒔖𒔗𒔘𒔙𒔚𒔛𒔜𒔝𒔞𒔟𒔠𒔡𒔢𒔣𒔤𒔥𒔦𒔧𒔨𒔩𒔪𒔫𒔬𒔭𒔮𒔯𒔰𒔱𒔲𒔳𒔴𒔵𒔶𒔷𒔸𒔹𒔺𒔻𒔼𒔽𒔾𒔿
12540 𒕀𒕁𒕂𒕃𒕄𒕅𒕆𒕇𒕈𒕉𒕊𒕋𒕌𒕍𒕎𒕏𒕐𒕑𒕒𒕓𒕔𒕕𒕖𒕗𒕘𒕙𒕚𒕛𒕜𒕝

, tässä toinen:

𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿
13040 𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿
13080 𓂀𓂁𓂂𓂃𓂄𓂅𓂆𓂇𓂈𓂉𓂊𓂋𓂌𓂍𓂎𓂏𓂐𓂑𓂒𓂓𓂔𓂕𓂖𓂗𓂘𓂙𓂚𓂛𓂜𓂝𓂞𓂟𓂠𓂡𓂢𓂣𓂤𓂥𓂦𓂧𓂨𓂩𓂪𓂫𓂬𓂭𓂮𓂯𓂰𓂱𓂲𓂳𓂴𓂵𓂶𓂷𓂸𓂹𓂺𓂻𓂼𓂽𓂾𓂿
130c0 𓃀𓃁𓃂𓃃𓃄𓃅𓃆𓃇𓃈𓃉𓃊𓃋𓃌𓃍𓃎𓃏𓃐𓃑𓃒𓃓𓃔𓃕𓃖𓃗𓃘𓃙𓃚𓃛𓃜𓃝𓃞𓃟𓃠𓃡𓃢𓃣𓃤𓃥𓃦𓃧𓃨𓃩𓃪𓃫𓃬𓃭𓃮𓃯𓃰𓃱𓃲𓃳𓃴𓃵𓃶𓃷𓃸𓃹𓃺𓃻𓃼𓃽𓃾𓃿
13100 𓄀𓄁𓄂𓄃𓄄𓄅𓄆𓄇𓄈𓄉𓄊𓄋𓄌𓄍𓄎𓄏𓄐𓄑𓄒𓄓𓄔𓄕𓄖𓄗𓄘𓄙𓄚𓄛𓄜𓄝𓄞𓄟𓄠𓄡𓄢𓄣𓄤𓄥𓄦𓄧𓄨𓄩𓄪𓄫𓄬𓄭𓄮𓄯𓄰𓄱𓄲𓄳𓄴

, ja tässä:

 2000            ‌‍‎‏‐‑‒–—―‖‗‘’‚‛“”„‟†‡•‣․‥…‧
‪‫‬‭‮ ‰‱′″‴‵‶‷‸‹›※‼‽‾‿
 2040 ⁀⁁⁂⁃⁄⁅⁆⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁒⁓⁔⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞ ⁠⁡⁢⁣⁤⁥⁦⁧⁨⁩⁰ⁱ⁲⁳⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ
 2080 ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎₏ₐₑₒₓₔₕₖₗₘₙₚₛₜ₝₞₟₠₡₢₣₤₥₦₧₨₩₪₫€₭₮₯₰₱₲₳₴₵₶₷₸₹₺₻₼₽₾₿
 20c0 ⃀⃁⃂⃃⃄⃅⃆⃇⃈⃉⃊⃋⃌⃍⃎⃏⃱⃲⃳⃴⃵⃶⃷⃸⃹⃺⃻⃼⃽⃾⃿
 2100 ℀℁ℂ℃℄℅℆ℇ℈℉ℊℋℌℍℎℏℐℑℒℓ℔ℕ№℗℘ℙℚℛℜℝ℞℟℠℡™℣ℤ℥Ω℧ℨ℩KÅℬℭ℮ℯℰℱℲℳℴℵℶℷℸℹ℺℻ℼℽℾℿ
 2140 ⅀⅁⅂⅃⅄ⅅⅆⅇⅈⅉ⅊⅋⅌⅍ⅎ⅏⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿ
 2180 ↀↁↂↃↄↅↆↇↈ↉↊↋↌↍↎↏←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿
 21c0 ⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇫⇬⇭⇮⇯⇰⇱⇲⇳⇴⇵⇶⇷⇸⇹⇺
㊥㊦㊧㊨㊩㊪㊫㊬㊭㊮㊯㊰㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿
 32c0 ㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㋌㋍㋎㋏㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝㋞㋟㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽㋾㋿
 3300 ㌀㌁㌂㌃㌄㌅㌆㌇㌈㌉㌊㌋㌌㌍㌎㌏㌐㌑㌒㌓㌔㌕㌖㌗㌘㌙㌚㌛㌜㌝㌞㌟㌠㌡㌢㌣㌤㌥㌦㌧㌨㌩㌪㌫㌬㌭㌮㌯㌰㌱㌲㌳㌴㌵㌶㌷㌸㌹㌺㌻㌼㌽㌾㌿
 3340 ㍀㍁㍂㍃㍄㍅㍆㍇㍈㍉㍊㍋㍌㍍㍎㍏㍐㍑㍒㍓㍔㍕㍖㍗㍘㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍱㍲㍳㍴㍵㍶㍷㍸㍹㍺㍻㍼㍽㍾㍿
 3380 ㎀㎁㎂㎃㎄㎅㎆㎇㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿
 33c0 ㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏋㏌㏍㏎㏏㏐㏑㏒㏓㏔㏕㏖㏗㏘㏙㏚㏛㏜㏝㏞㏟㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㏿

. Loput emojit:

1bb80 𛮀𛮁𛮂𛮃𛮄𛮅𛮆𛮇𛮈𛮉𛮊𛮋𛮌𛮍𛮎𛮏𛮐𛮑𛮒𛮓𛮔𛮕𛮖𛮗𛮘𛮙𛮚𛮛𛮜𛮝𛮞𛮟𛮠𛮡𛮢𛮣𛮤𛮥𛮦𛮧𛮨𛮩𛮪𛮫𛮬𛮭𛮮𛮯𛮰𛮱𛮲𛮳𛮴𛮵𛮶𛮷𛮸𛮹𛮺𛮻𛮼𛮽𛮾𛮿
1bbc0 𛯀𛯁𛯂𛯃𛯄𛯅𛯆𛯇𛯈𛯉𛯊𛯋𛯌𛯍𛯎𛯏𛯐𛯑𛯒𛯓𛯔𛯕𛯖𛯗𛯘𛯙𛯚𛯛𛯜𛯝𛯞𛯟𛯠𛯡𛯢𛯣𛯤𛯥𛯦𛯧𛯨𛯩𛯪𛯫𛯬𛯭𛯮𛯯𛯰𛯱𛯲𛯳𛯴𛯵𛯶𛯷𛯸𛯹𛯺𛯻𛯼𛯽𛯾𛯿
1bc00 𛰀𛰁𛰂𛰃𛰄𛰅𛰆𛰇𛰈𛰉𛰊𛰋𛰌𛰍𛰎𛰏𛰐𛰑𛰒𛰓𛰔𛰕𛰖𛰗𛰘𛰙𛰚𛰛𛰜𛰝𛰞𛰟𛰠𛰡𛰢𛰣𛰤𛰥𛰦𛰧𛰨𛰩𛰪𛰫𛰬𛰭𛰮𛰯𛰰𛰱𛰲𛰳𛰴𛰵𛰶𛰷𛰸𛰹𛰺𛰻𛰼𛰽𛰾𛰿
1bc40 𛱀𛱁𛱂𛱃𛱄𛱅𛱆𛱇𛱈𛱉𛱊𛱋𛱌𛱍𛱎𛱏𛱐𛱑𛱒𛱓𛱔𛱕𛱖𛱗𛱘𛱙𛱚𛱛𛱜𛱝𛱞𛱟𛱠𛱡𛱢𛱣𛱤𛱥𛱦𛱧𛱨𛱩𛱪𛱫𛱬𛱭𛱮𛱯𛱰𛱱𛱲𛱳𛱴𛱵𛱶𛱷𛱸𛱹𛱺𛱻𛱼𛱽𛱾𛱿
1bc80 𛲀𛲁𛲂𛲃𛲄𛲅𛲆𛲇𛲈𛲉𛲊𛲋𛲌𛲍𛲎𛲏𛲐𛲑𛲒𛲓𛲔𛲕𛲖𛲗𛲘𛲙𛲚𛲛𛲜𛲝𛲞𛲟𛲠𛲡𛲢𛲣𛲤𛲥𛲦𛲧𛲨𛲩𛲪𛲫𛲬𛲭𛲮𛲯𛲰𛲱𛲲𛲳𛲴𛲵𛲶𛲷𛲸𛲹𛲺𛲻𛲼𛲽𛲾𛲿
1bcc0 𛳀𛳁𛳂𛳃𛳄𛳅𛳆𛳇𛳈𛳉𛳊𛳋𛳌𛳍𛳎𛳏𛳐𛳑𛳒𛳓𛳔𛳕𛳖𛳗𛳘𛳙𛳚𛳛𛳜𛳝𛳞𛳟𛳠𛳡𛳢𛳣𛳤𛳥𛳦𛳧𛳨𛳩𛳪𛳫𛳬𛳭𛳮𛳯𛳰𛳱𛳲𛳳𛳴𛳵𛳶𛳷𛳸𛳹𛳺𛳻𛳼𛳽𛳾𛳿
1bd00 𛴀𛴁𛴂𛴃𛴄𛴅𛴆𛴇𛴈𛴉𛴊𛴋𛴌𛴍𛴎𛴏𛴐𛴑𛴒𛴓𛴔𛴕𛴖𛴗𛴘𛴙𛴚
𖟀𖟁𖟂𖟃𖟄𖟅𖟆𖟇𖟈𖟉𖟊𖟋𖟌𖟍𖟎𖟏𖟐𖟑𖟒𖟓𖟔𖟕𖟖𖟗𖟘𖟙𖟚𖟛𖟜𖟝𖟞𖟟𖟠𖟡𖟢𖟣𖟤𖟥𖟦𖟧𖟨𖟩𖟪𖟫𖟬𖟭𖟮𖟯𖟰𖟱𖟲𖟳𖟴𖟵𖟶𖟷𖟸𖟹𖟺𖟻𖟼𖟽𖟾𖟿
16800 𖠀𖠁𖠂𖠃𖠄𖠅𖠆𖠇𖠈𖠉𖠊𖠋𖠌𖠍𖠎𖠏𖠐𖠑𖠒𖠓𖠔𖠕𖠖𖠗𖠘𖠙𖠚𖠛𖠜𖠝𖠞𖠟𖠠𖠡𖠢𖠣𖠤𖠥𖠦𖠧𖠨𖠩𖠪𖠫𖠬𖠭𖠮𖠯𖠰𖠱𖠲𖠳𖠴𖠵𖠶𖠷𖠸𖠹𖠺𖠻𖠼𖠽𖠾𖠿
16840 𖡀𖡁𖡂𖡃𖡄𖡅𖡆𖡇𖡈𖡉𖡊𖡋𖡌𖡍𖡎𖡏𖡐𖡑𖡒𖡓𖡔𖡕𖡖𖡗𖡘𖡙𖡚𖡛𖡜𖡝𖡞𖡟𖡠𖡡𖡢𖡣𖡤𖡥𖡦𖡧𖡨𖡩𖡪𖡫𖡬𖡭𖡮𖡯𖡰𖡱𖡲𖡳𖡴𖡵𖡶𖡷𖡸𖡹𖡺𖡻𖡼𖡽𖡾𖡿
16880 𖢀𖢁𖢂𖢃𖢄𖢅𖢆𖢇𖢈𖢉𖢊𖢋𖢌𖢍𖢎𖢏𖢐𖢑𖢒𖢓𖢔𖢕𖢖𖢗𖢘𖢙𖢚𖢛𖢜𖢝𖢞𖢟𖢠𖢡𖢢𖢣𖢤𖢥𖢦𖢧𖢨𖢩𖢪𖢫𖢬𖢭𖢮𖢯𖢰𖢱𖢲𖢳𖢴𖢵𖢶𖢷𖢸𖢹𖢺𖢻𖢼𖢽𖢾𖢿
168c0 𖣀𖣁𖣂𖣃𖣄𖣅𖣆𖣇𖣈𖣉𖣊𖣋𖣌𖣍𖣎𖣏𖣐𖣑𖣒𖣓𖣔𖣕𖣖𖣗𖣘𖣙𖣚𖣛𖣜𖣝𖣞𖣟𖣠𖣡𖣢𖣣𖣤𖣥𖣦𖣧𖣨𖣩𖣪𖣫𖣬𖣭𖣮𖣯𖣰𖣱𖣲𖣳𖣴𖣵𖣶𖣷𖣸𖣹𖣺𖣻𖣼𖣽𖣾𖣿
16900 𖤀𖤁𖤂𖤃𖤄𖤅𖤆𖤇𖤈𖤉𖤊𖤋𖤌𖤍𖤎𖤏𖤐𖤑𖤒𖤓𖤔𖤕𖤖𖤗𖤘𖤙𖤚𖤛𖤜𖤝𖤞𖤟𖤠𖤡𖤢𖤣𖤤𖤥𖤦𖤧𖤨𖤩𖤪𖤫𖤬𖤭𖤮𖤯𖤰𖤱𖤲𖤳𖤴𖤵𖤶𖤷𖤸𖤹𖤺𖤻𖤼𖤽𖤾𖤿
16940 𖥀𖥁𖥂𖥃𖥄𖥅𖥆𖥇𖥈𖥉𖥊𖥋𖥌𖥍𖥎𖥏𖥐𖥑𖥒𖥓𖥔𖥕𖥖𖥗𖥘𖥙𖥚𖥛𖥜𖥝𖥞𖥟𖥠𖥡𖥢𖥣𖥤𖥥𖥦𖥧𖥨𖥩𖥪𖥫𖥬𖥭𖥮𖥯𖥰𖥱𖥲𖥳𖥴𖥵𖥶𖥷𖥸𖥹𖥺𖥻𖥼𖥽𖥾𖥿
16980 𖦀𖦁𖦂𖦃𖦄𖦅𖦆𖦇𖦈𖦉𖦊𖦋𖦌𖦍𖦎𖦏𖦐𖦑𖦒𖦓𖦔𖦕𖦖𖦗𖦘𖦙𖦚𖦛𖦜𖦝𖦞𖦟𖦠𖦡𖦢𖦣𖦤𖦥𖦦𖦧𖦨𖦩𖦪𖦫𖦬𖦭𖦮𖦯𖦰𖦱𖦲𖦳𖦴𖦵𖦶𖦷𖦸𖦹𖦺𖦻𖦼𖦽𖦾𖦿
169c0 𖧀𖧁𖧂𖧃𖧄𖧅𖧆𖧇𖧈𖧉𖧊𖧋𖧌𖧍𖧎𖧏𖧐𖧑𖧒𖧓𖧔𖧕𖧖𖧗𖧘𖧙𖧚𖧛𖧜𖧝𖧞𖧟𖧠𖧡𖧢𖧣𖧤𖧥𖧦𖧧𖧨𖧩𖧪𖧫𖧬𖧭𖧮𖧯𖧰𖧱𖧲𖧳𖧴𖧵𖧶𖧷𖧸𖧹𖧺𖧻𖧼𖧽𖧾𖧿
16a00 𖨀𖨁𖨂𖨃𖨄𖨅𖨆𖨇𖨈𖨉𖨊𖨋𖨌𖨍𖨎𖨏𖨐𖨑𖨒𖨓𖨔𖨕𖨖𖨗𖨘𖨙𖨚𖨛𖨜𖨝𖨞𖨟𖨠𖨡𖨢𖨣𖨤𖨥𖨦𖨧𖨨𖨩𖨪𖨫𖨬𖨭𖨮𖨯𖨰𖨱𖨲𖨳𖨴𖨵𖨶𖨷𖨸𖨹𖨺𖨻𖨼𖨽𖨾𖨿
16a40 𖩀𖩁𖩂𖩃𖩄𖩅𖩆𖩇𖩈𖩉𖩊𖩋𖩌𖩍𖩎𖩏𖩐𖩑𖩒𖩓𖩔𖩕𖩖𖩗𖩘𖩙𖩚𖩛𖩜𖩝𖩞𖩟𖩠𖩡𖩢𖩣𖩤𖩥𖩦𖩧𖩨𖩩𖩪𖩫𖩬𖩭𖩮𖩯𖩰𖩱𖩲𖩳𖩴𖩵𖩶𖩷𖩸𖩹𖩺𖩻𖩼𖩽𖩾𖩿
16a80 𖪀𖪁𖪂𖪃𖪄𖪅𖪆𖪇𖪈𖪉𖪊𖪋𖪌𖪍𖪎𖪏𖪐𖪑𖪒𖪓𖪔𖪕𖪖𖪗𖪘𖪙𖪚𖪛𖪜𖪝𖪞𖪟𖪠𖪡𖪢𖪣𖪤𖪥𖪦𖪧𖪨𖪩𖪪𖪫𖪬𖪭𖪮𖪯𖪰𖪱𖪲𖪳𖪴𖪵𖪶𖪷𖪸𖪹𖪺𖪻𖪼𖪽𖪾𖪿

. Tässä kaikki utf-8 merkit (utf-8 merkit, emojit): (ilmeisesti ei mahtunut, paste ei onnistunut…)

Ei se mitään aina pätee sano se koodilla: tässä vaihteeksi (ceetä:)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ulonglong unsigned long long

unsigned char *procname = "utf-8";
static unsigned char *programname = "Utf-8 version 0.04 ©";
static unsigned char *copyright = "Copyright (c) 1998-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";

#define DEBUG42 2

// crosscheck utf8 characters
#define DEBUG43 2

#ifdef DEBUG42
int verbose1 = 0;
#ifdef DEBUG43
int verbose2 = 0;
#endif
#endif

int size = -1, cwords = 0, sspace = 0;
static int pwords = 0, slineno = 1, plinesdigits = 5, charwidth = 1;

#ifdef DEBUG43

static void utf8tocode(ulonglong *code, unsigned char *buf2)
{
  unsigned char *buf;
  
  *code = 0;
  buf = buf2;
  
  if(*buf <= 0x7f) {                  // 0xxxxxxx
    *code = *buf;
  } else if(*buf < 0xc0) {            // 110xxxxx 10xxxxxx
    *code = 0;
  } else if(*buf < 0xe0) {            // 110xxxxx 10xxxxxx
    *code = *buf++ & 0x1f;
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xf0) {            // 1110xxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x0f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf<0xf8) {            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x07;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfc) {            // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x03;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfe) {            // 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x01;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xff) {            // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf == 0xff) {            // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  }
#ifdef DEBUG43

  if(verbose2) {
    int c;
    
    fprintf(stdout, "bin2: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      if(c > 0)
	fprintf(stdout, "|");
      for(int d = 7; d >= 0; d--)
	fprintf(stdout, "%d", buf2[c] >> d & 1);
    }
    
    fprintf(stdout, ", oct2:");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      fprintf(stdout, " %3o", buf2[c]);
    }
    
    fprintf(stdout, ", utf8_2: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      fprintf(stdout,"%02x", buf2[c]);
    }
    
    fprintf(stdout, ", char2: %s", buf2);

    fprintf(stdout,", char2bin: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      if(c > 0)
	fprintf(stdout,"|");
      for(int d = 7; d >= 0; d--) {
	fprintf(stdout,"%d", buf2[c] >> d & 1);
      }
    }

    fprintf(stdout, ", cp2: %llx", *code);
    fprintf(stdout, ", cp2bin:");
    int print = 0;
    for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
      int bit = (*code >> c) & 1;
      if(bit != 0)
	print = 1;
      if(print) {
	fprintf(stdout, "%d", bit);
	if(c > 0 && c % 8 == 0)
	  fprintf(stdout, "|");
      }
    }

    fprintf(stdout, ", cp2oct:");
    fprintf(stdout, "%llo", *code);

    fprintf(stdout,"\n");    
  }

#endif
}

#endif

static void codetoutf8(unsigned char *buf2, ulonglong code)
{
  unsigned char *buf;

  buf = buf2;
  if(code <= 0x7f) {
    *buf++ = code;
  } else if(code <= 0x7ff) {            // 110xxxxx 10xxxxxx
    *buf++ = (0xc0 | ((code >> 6) & 0x1f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0xffff) {           // 1110xxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xe0 | ((code >> 12) & 0x0f));
    *buf++ = (0x80 | ((code >> 6) & 0x3f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0x10ffff) {         // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xf0 | ((code >> 18) & 0x07));
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffff) {        // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xf8 | ((code >> 24) & 0x03));
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x7fffffff) {       // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfc | ((code >> 30) & 0x01));
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0xfffffffff) {      // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfe);
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffffffff) {    // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xff);
    *buf++ = (0x80 | ((code >> 36) & 0x3f));      
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  }
  *buf = '\0';

#ifdef DEBUG42

  if(verbose1) {
    int c, print;

    fprintf(stdout,"cp: %llx", code);
    
    fprintf(stdout,", cpbin:");
    
    print = 0;
    for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
      int bit = (code >> c) & 1;
      if(bit != 0)
	print = 1;
      if(print) {
	fprintf(stdout,"%d", bit);
	if(c > 0 && c % 8 == 0)
	  fprintf(stdout,"|");
      }
    }
    
    fprintf(stdout,", cpoct:");
    print = 0;
    fprintf(stdout,"%llo", code);
    
    fprintf(stdout,", utf8: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      fprintf(stdout,"%02x", buf2[c]);
    }
    
    fprintf(stdout, ", char: %s", buf2);
    
    fprintf(stdout,", charbin: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      if(c > 0)
	fprintf(stdout,"|");
      for(int d = 7; d >= 0; d--) {
	fprintf(stdout,"%d", buf2[c] >> d & 1);
      }
    }
    
    fprintf(stdout,", oct:");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      fprintf(stdout," %3o", buf2[c]);
    }
    
    fprintf(stdout, ", utf8: ");
    for(c = 0; c < 8; c++) {
      if(buf2[c] == '\0')
	break;
      fprintf(stdout,"%02x", buf2[c]);
    }
    
    fprintf(stdout,", char: %s", buf2);
    //fprintf(stdout,"\n");

    fprintf(stdout,"\n");
  }

#ifdef DEBUG43
  ulonglong code2;
  
  utf8tocode(&code2, buf2);
  if(code != code2)
    fprintf(stdout,"***** ERROR *****");
    
#endif
  
#endif
}

static int calc_spaces()
{
  int spaces;

  spaces = 0;
  
  if(sspace >= 2 &&
     // space between word groups
     ( (cwords > 0 && cwords % sspace == 0) ||
       // space after linenumber
       // are not printed if
       // not printing linenumber
       (slineno && cwords == 0) ) )
    spaces++;
    
  if(sspace &&
     // space between words
     ( (cwords > 0) ||
       // space after linenumber
       (slineno && cwords == 0) ) ) 
    spaces++;

  return(spaces);
}

static void print_spaces(char spacechar)
{
  int sp;

  for(sp = calc_spaces(); sp > 0; sp--)
    fputc(spacechar, stdout);
}

static ulonglong lines = 10, plines = 0, ptotallines = 0;
ulonglong xlines = 0;


void printcolumns(int offset, int base, int startwith, int columns, ulonglong *clines) // 2023 JariK
{
  //---------11111111112222222222333333333344444444445555555555666666666677
  //12345678901234567890123456789012345678901234567890123456789012345678901
  //=======================================================================
  //00000 86747100388687087416829400778878989202760594993130062980826178851
  //00001 36862623069143814543525935285460059703805218323534266522497684582
  
  int c, d, digit, nonzero;
  unsigned char digits[0x10] = "0123456789abcdef";

  *clines = 0;

  if(base == 2)
    c = 1 << 12;
  else if(base == 8)
    c = 01000000;
  else if(base == 10)
    c = 1000000;
  else if(base == 16)
    c = 0x1000000;
  else {
    fprintf(stdout,"%s: printcolumns():", procname);
    fprintf(stdout," illegal base %d", base);
    fprintf(stdout,"\n");
    exit(1);
  }

  for(;c >= 1; c /= base) { // lines, 100000's, 10000's, 1000's ... 1's
    if(c >= columns)
      continue;

    for(d = 0; d < offset; d++)
      fprintf(stdout," "); // spaces in beginning of row

    nonzero = 0;
    
    for(d = startwith; d < columns + startwith; d++) { // column numbers
      digit = (d / c) % base;
      if(digit != 0)
	nonzero = 1;
      if(nonzero || c == 1)
	fprintf(stdout,"%c", digits[digit]); // nonzero digits after first nonzero
      else
	fprintf(stdout,"-"); // zeroes in beginning of row
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  if(pwords > 0) {
    if(slineno) {
      for(c = 0; c <= plinesdigits; c++) // +1
	fprintf(stdout,"-");
    }
    for(cwords = 0; cwords < pwords; cwords++) {
      print_spaces('-');
      fprintf(stdout,"w");
      if(charwidth == 2)
	fprintf(stdout,"-");
      for(c = 0; c < size - 1; c++) {
	fprintf(stdout,"-");
	if(charwidth == 2)
	  fprintf(stdout,"-");
      }
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  for(d = 0; d < offset; d++)
    fprintf(stdout," "); // spaces in beginning of row
  for(d = startwith; d < columns + startwith; d++)
    fprintf(stdout,"=");
  fprintf(stdout,"\n");
  (*clines)++;
}


#define KILO 1024

void readablelonglong(FILE *fp1, ulonglong ll2) // 2023 JariK
{
  int c;
  ulonglong multiplier, ll = ll2;
  
  // B = byte
  // K = kilo   10^3   2^10
  // M = mega   10^6   2^20
  // G = giga   10^9   2^30
  // T = tera   10^12  2^40
  // P = peta   10^15  2^50
  // E = exa    10^18  2^60
  // Z = zetta  10^21  2^70
  // Y = yotta  10^24  2^80

  char units[] = "BKMGTPEZY";

  c = 0;
  multiplier = 1;
  while(ll >= KILO) {
    ll /= KILO;
    multiplier *= KILO;
    c++;
  }

  if(ll * multiplier != ll2)
    fprintf(fp1,"~"); // approximately

  fprintf(fp1,"%llu%c", ll, units[c]);
}

void fprintfcharacter(FILE *fp1, unsigned char *p) // 2023 JariK
{
  fputc(*p, fp1); // print first char
  if(*p > 0xbf) { // first char utf8
    p++;
    for(;;) { // print rest of the utf8 chars
      if(*p > 0xbf || // new utf8 character
	 *p < 0x80 || // ascii character
	 *p == '\0') // end of string
	break;
      fputc(*p, fp1);
      p++;
    }
  }
}

int getdigit(unsigned char *p) // 2023 JariK
{
  int digit;
  
  if(*p >= '0' && *p <= '9')
    digit = *p - '0';
  else if(*p >= 'a' && *p <= 'z')
    digit = (*p - 'a') + 10;
  else if(*p >= 'A' && *p <= 'Z')
    digit = (*p - 'A') + 10;
  else
    digit = -1; // not found, illegal

  return(digit);
}

//#define KILO 1000
#define KILO 1024

ulonglong getlonglong(unsigned char *p2) // 2023 JariK
{
  int digit, base = 10;
  unsigned char *p = p2;
  ulonglong totll, ll, prevll, multiplier;
  
  totll = 0;

  while(*p != '\0') { // works also: 1g100m & 1m20k and 1t1t etc...

    unsigned char *prevp = p;
    
    if(!strncmp("0x", p, 2)) {
      base = 16;
      p += 2;
      
    } else if(!strncmp("0d", p, 2)) {
      base = 10;
      p += 2;
      
    } else if(!strncmp("0o", p, 2)) {
      base = 8;
      p += 2;
      
    } else if(!strncmp("0b", p, 2)) {
      base = 2;
      p += 2;
      
    }
    
    ll = 0;
    while((digit = getdigit(p)) != -1 && digit < base) {
      ll = ll * base + digit;
      p++;
    }
    
    multiplier = 1;
    
    if(*p == 'k' || *p == 'K') {
      multiplier = KILO;
      p++;
      
    } else if(*p == 'm' || *p == 'M') {
      multiplier = (KILO * KILO);
      p++;
      
    } else if(*p == 'g' || *p == 'G') {
      multiplier = (KILO * KILO * KILO);
      p++;
      
    } else if(*p == 't' || *p == 'T') {
      multiplier = ((ulonglong)KILO * KILO * KILO * KILO);
      p++;
      
    } else if(*p == 'p' || *p == 'P') {
      multiplier = ((ulonglong)KILO * KILO * KILO * KILO * KILO);
      p++;
      
    } else if(*p == 'e' || *p == 'E') {
      multiplier = ((ulonglong)KILO * KILO * KILO * KILO * KILO * KILO);
      p++;
      
    }
    
    prevll = ll;
    ll *= multiplier;
    if(ll / multiplier != prevll) {
      fflush(stdout);
      fprintf(stderr,"%s: multiply overflow", procname);
      fprintf(stderr,", string:'%s'", p2);
      fprintf(stderr,", digit:'");
      fprintfcharacter(stderr, p);
      fprintf(stderr,"'");
      fprintf(stderr,", value: %d", digit);
      fprintf(stderr,", base: %d", base);
      fprintf(stderr,", ll: %llu", prevll);
      fprintf(stderr,", multiplier: %llu", multiplier);
      fprintf(stderr,"\n");
      fflush(stderr);
    }
  
    if(*p == 'b' || *p == 'B') // remove last b (for bytes in 1tb, 1gb or 1mb)
      p++;
    
    totll += ll;

#ifdef DEBUG32
    fprintf(stderr,"string:'%s'", p2);
    fprintf(stderr,", base:%d(", base);
    readablelonglong(stderr, base);
    fprintf(stderr,")");
    fprintf(stderr,", multiplier:%llu(", multiplier);
    readablelonglong(stderr, multiplier);
    fprintf(stderr,")");
    fprintf(stderr,", prevll:%llu(", prevll);
    readablelonglong(stderr, prevll);
    fprintf(stderr,")");
    fprintf(stderr,", ll:%llu(", ll);
    readablelonglong(stderr, ll);
    fprintf(stderr,")");
    fprintf(stderr,", totll:%llu(", totll);
    readablelonglong(stderr, totll);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
#endif
    
    if(prevp == p) // no progress
      break;
  }
  
  if(*p != '\0') {
    fflush(stdout);
    fprintf(stderr,"%s: illegal digit", procname);
    fprintf(stderr,", string:'%s'", p2);
    fprintf(stderr,", digit:'");
    fprintfcharacter(stderr, p);
    fprintf(stderr,"'");
    fprintf(stderr,", value: %d", digit);
    fprintf(stderr,", base: %d(", base);
    readablelonglong(stderr, base);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
    fflush(stderr);
  }

  return(totll);
}

ulonglong startcp = 0;
ulonglong endcp = 65535 * 4;

int iprintcolumns = 1;

void utf8()
{
  ulonglong c;
  int utf8output = 0;

  if(iprintcolumns)
    printcolumns(6, 0x10, 0, 64, &xlines);

  for(c = startcp; c < endcp; c++) {
    //for(c = 0x2800; c < 0x2900; c++) { // braille
    unsigned char buffer10[10];
    if(c % 64 == 0) {
      if(c > 0) {
	fprintf(stdout,"\n");
	utf8output = 0;
      }
      fprintf(stdout,"%5llx ", c);
      utf8output = 1; 
    }
    if(c >= 0 && c < 32) {
      c += 31;
      fprintf(stdout, "%-32s", "--- control characters ---");
      utf8output = 1;
    } else if(c >= 128 && c < 256) {
      c += 31;
      fprintf(stdout, "%-32s", "--- utf8 characters ---");
      utf8output = 1;
    } else {
      codetoutf8(buffer10, c);
      fprintf(stdout,"%s", buffer10);
      utf8output = 1;
    }
  }
  if(utf8output)
    fprintf(stdout,"\n");
  fflush(stdout);
}

unsigned char *startcp_str = NULL;
unsigned char *endcp_str = NULL;

void main(int argc, char *argv[])
{
  int c;
  
  //
  // look thru command line parameters
  //
  int help = 0;

  for(c = 1; c < argc; c++) {
    if(!strcmp("--copyright", argv[c]) ||
       !strcmp("--version", argv[c])) {
      fprintf(stdout,"%s, ", programname);
      fprintf(stdout,"%s", copyright);
      fprintf(stdout,"\n");
#ifdef SHA256
      fprintf(stdout,"sha256(");
      for(int c = 0; c < HashLen; c++) {
	fprintf(stdout, "%02x", programfiledigest[c]);
      }
      fprintf(stdout, "\n");
#endif
      help = 0;
      exit(1);
      
    } else if(!strcmp("--help", argv[c])) {
      fprintf(stdout,"%s", copyright);
#ifdef SHA256
      fprintf(stderr,"\nsha256(");
      for(int c = 0; c < HashLen; c++) {
	fprintf(stderr, "%02x", programfiledigest[c]);
      }
#endif
      fprintf(stdout,"\n\n");

#ifdef DEBUG42
    } else if(!strcmp("--verbose1", argv[c])) {
      verbose1 = 1;
#ifdef DEBUG43
    } else if(!strcmp("--verbose2", argv[c])) {
      verbose2 = 1;
#endif
#endif
    } else if(!strcmp("--printcolumns", argv[c])) {
      iprintcolumns = !iprintcolumns;
      fprintf(stdout,"iprintcolumns=%d\n",
	      iprintcolumns);

    } else if(!strncmp("--startcp", argv[c], 9)) {
      if(*(argv[c] + 9) != '\0') {
	startcp_str = argv[c] + 9;
	startcp = getlonglong(startcp_str);

      } else if(c + 1 < argc) {
	startcp_str = argv[c + 1];
	startcp = getlonglong(startcp_str);
	c++;
      }
      fprintf(stdout,"startcp=%llx(%s)\n",
	      startcp, startcp_str);
    } else if(!strncmp("--endcp", argv[c], 7)) {
      if(*(argv[c] + 7) != '\0') {
	endcp_str = argv[c] + 7;
	endcp = getlonglong(endcp_str);

      } else if(c + 1 < argc) {
	endcp_str = argv[c + 1];
	endcp = getlonglong(endcp_str);
	c++;
      }
      fprintf(stdout,"endcp=%llx(%s)\n",
	      endcp, endcp_str);

    } else {
      fprintf(stderr,"%s: invalid option %s\n", procname, argv[c]);
      exit(1);

    }
  }
  utf8();
}

(ja kuten aina ennen ajamista lukekaa koodi läpi ettei siinä ole haitallista materiaalia…).

Edellisen debukkirivejä DEBUG42 ja DEBUG43 päällä:

      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
    0 --- control characters ---      codepoint: 20, bin:100000, oct:40, utf8: 20, bin: 00100000, oct:  40, character:  , oct:40.ok
 codepoint: 21, bin:100001, oct:41, utf8: 21, bin: 00100001, oct:  41, character: !, oct:41.ok
!codepoint: 22, bin:100010, oct:42, utf8: 22, bin: 00100010, oct:  42, character: ", oct:42.ok
"codepoint: 23, bin:100011, oct:43, utf8: 23, bin: 00100011, oct:  43, character: #, oct:43.ok
#codepoint: 24, bin:100100, oct:44, utf8: 24, bin: 00100100, oct:  44, character: $, oct:44.ok
$codepoint: 25, bin:100101, oct:45, utf8: 25, bin: 00100101, oct:  45, character: %, oct:45.ok
%codepoint: 26, bin:100110, oct:46, utf8: 26, bin: 00100110, oct:  46, character: &, oct:46.ok
&codepoint: 27, bin:100111, oct:47, utf8: 27, bin: 00100111, oct:  47, character: ', oct:47.ok
'codepoint: 28, bin:101000, oct:50, utf8: 28, bin: 00101000, oct:  50, character: (, oct:50.ok
(codepoint: 29, bin:101001, oct:51, utf8: 29, bin: 00101001, oct:  51, character: ), oct:51.ok
)codepoint: 2a, bin:101010, oct:52, utf8: 2a, bin: 00101010, oct:  52, character: *, oct:52.ok
*codepoint: 2b, bin:101011, oct:53, utf8: 2b, bin: 00101011, oct:  53, character: +, oct:53.ok
+codepoint: 2c, bin:101100, oct:54, utf8: 2c, bin: 00101100, oct:  54, character: ,, oct:54.ok
,codepoint: 2d, bin:101101, oct:55, utf8: 2d, bin: 00101101, oct:  55, character: -, oct:55.ok
-codepoint: 2e, bin:101110, oct:56, utf8: 2e, bin: 00101110, oct:  56, character: ., oct:56.ok
.codepoint: 2f, bin:101111, oct:57, utf8: 2f, bin: 00101111, oct:  57, character: /, oct:57.ok
/codepoint: 30, bin:110000, oct:60, utf8: 30, bin: 00110000, oct:  60, character: 0, oct:60.ok
0codepoint: 31, bin:110001, oct:61, utf8: 31, bin: 00110001, oct:  61, character: 1, oct:61.ok
1codepoint: 32, bin:110010, oct:62, utf8: 32, bin: 00110010, oct:  62, character: 2, oct:62.ok
2codepoint: 33, bin:110011, oct:63, utf8: 33, bin: 00110011, oct:  63, character: 3, oct:63.ok
3codepoint: 34, bin:110100, oct:64, utf8: 34, bin: 00110100, oct:  64, character: 4, oct:64.ok
4codepoint: 35, bin:110101, oct:65, utf8: 35, bin: 00110101, oct:  65, character: 5, oct:65.ok
5codepoint: 36, bin:110110, oct:66, utf8: 36, bin: 00110110, oct:  66, character: 6, oct:66.ok
6codepoint: 37, bin:110111, oct:67, utf8: 37, bin: 00110111, oct:  67, character: 7, oct:67.ok
7codepoint: 38, bin:111000, oct:70, utf8: 38, bin: 00111000, oct:  70, character: 8, oct:70.ok
8codepoint: 39, bin:111001, oct:71, utf8: 39, bin: 00111001, oct:  71, character: 9, oct:71.ok
9codepoint: 3a, bin:111010, oct:72, utf8: 3a, bin: 00111010, oct:  72, character: :, oct:72.ok
:codepoint: 3b, bin:111011, oct:73, utf8: 3b, bin: 00111011, oct:  73, character: ;, oct:73.ok
;codepoint: 3c, bin:111100, oct:74, utf8: 3c, bin: 00111100, oct:  74, character: <, oct:74.ok
<codepoint: 3d, bin:111101, oct:75, utf8: 3d, bin: 00111101, oct:  75, character: =, oct:75.ok
=codepoint: 3e, bin:111110, oct:76, utf8: 3e, bin: 00111110, oct:  76, character: >, oct:76.ok
>codepoint: 3f, bin:111111, oct:77, utf8: 3f, bin: 00111111, oct:  77, character: ?, oct:77.ok
?
   40 codepoint: 40, bin:1000000, oct:100, utf8: 40, bin: 01000000, oct: 100, character: @, oct:100.ok
@codepoint: 41, bin:1000001, oct:101, utf8: 41, bin: 01000001, oct: 101, character: A, oct:101.ok
Acodepoint: 42, bin:1000010, oct:102, utf8: 42, bin: 01000010, oct: 102, character: B, oct:102.ok
Bcodepoint: 43, bin:1000011, oct:103, utf8: 43, bin: 01000011, oct: 103, character: C, oct:103.ok
Ccodepoint: 44, bin:1000100, oct:104, utf8: 44, bin: 01000100, oct: 104, character: D, oct:104.ok
Dcodepoint: 45, bin:1000101, oct:105, utf8: 45, bin: 01000101, oct: 105, character: E, oct:105.ok
Ecodepoint: 46, bin:1000110, oct:106, utf8: 46, bin: 01000110, oct: 106, character: F, oct:106.ok
Fcodepoint: 47, bin:1000111, oct:107, utf8: 47, bin: 01000111, oct: 107, character: G, oct:107.ok
Gcodepoint: 48, bin:1001000, oct:110, utf8: 48, bin: 01001000, oct: 110, character: H, oct:110.ok
Hcodepoint: 49, bin:1001001, oct:111, utf8: 49, bin: 01001001, oct: 111, character: I, oct:111.ok
Icodepoint: 4a, bin:1001010, oct:112, utf8: 4a, bin: 01001010, oct: 112, character: J, oct:112.ok
Jcodepoint: 4b, bin:1001011, oct:113, utf8: 4b, bin: 01001011, oct: 113, character: K, oct:113.ok
Kcodepoint: 4c, bin:1001100, oct:114, utf8: 4c, bin: 01001100, oct: 114, character: L, oct:114.ok
Lcodepoint: 4d, bin:1001101, oct:115, utf8: 4d, bin: 01001101, oct: 115, character: M, oct:115.ok
Mcodepoint: 4e, bin:1001110, oct:116, utf8: 4e, bin: 01001110, oct: 116, character: N, oct:116.ok
Ncodepoint: 4f, bin:1001111, oct:117, utf8: 4f, bin: 01001111, oct: 117, character: O, oct:117.ok
Ocodepoint: 50, bin:1010000, oct:120, utf8: 50, bin: 01010000, oct: 120, character: P, oct:120.ok
Pcodepoint: 51, bin:1010001, oct:121, utf8: 51, bin: 01010001, oct: 121, character: Q, oct:121.ok
Qcodepoint: 52, bin:1010010, oct:122, utf8: 52, bin: 01010010, oct: 122, character: R, oct:122.ok
Rcodepoint: 53, bin:1010011, oct:123, utf8: 53, bin: 01010011, oct: 123, character: S, oct:123.ok
Scodepoint: 54, bin:1010100, oct:124, utf8: 54, bin: 01010100, oct: 124, character: T, oct:124.ok
Tcodepoint: 55, bin:1010101, oct:125, utf8: 55, bin: 01010101, oct: 125, character: U, oct:125.ok
Ucodepoint: 56, bin:1010110, oct:126, utf8: 56, bin: 01010110, oct: 126, character: V, oct:126.ok
Vcodepoint: 57, bin:1010111, oct:127, utf8: 57, bin: 01010111, oct: 127, character: W, oct:127.ok
Wcodepoint: 58, bin:1011000, oct:130, utf8: 58, bin: 01011000, oct: 130, character: X, oct:130.ok
Xcodepoint: 59, bin:1011001, oct:131, utf8: 59, bin: 01011001, oct: 131, character: Y, oct:131.ok
Ycodepoint: 5a, bin:1011010, oct:132, utf8: 5a, bin: 01011010, oct: 132, character: Z, oct:132.ok
Zcodepoint: 5b, bin:1011011, oct:133, utf8: 5b, bin: 01011011, oct: 133, character: [, oct:133.ok
[codepoint: 5c, bin:1011100, oct:134, utf8: 5c, bin: 01011100, oct: 134, character: \, oct:134.ok
\codepoint: 5d, bin:1011101, oct:135, utf8: 5d, bin: 01011101, oct: 135, character: ], oct:135.ok
]codepoint: 5e, bin:1011110, oct:136, utf8: 5e, bin: 01011110, oct: 136, character: ^, oct:136.ok
^codepoint: 5f, bin:1011111, oct:137, utf8: 5f, bin: 01011111, oct: 137, character: _, oct:137.ok
_codepoint: 60, bin:1100000, oct:140, utf8: 60, bin: 01100000, oct: 140, character: `, oct:140.ok
`codepoint: 61, bin:1100001, oct:141, utf8: 61, bin: 01100001, oct: 141, character: a, oct:141.ok
acodepoint: 62, bin:1100010, oct:142, utf8: 62, bin: 01100010, oct: 142, character: b, oct:142.ok
bcodepoint: 63, bin:1100011, oct:143, utf8: 63, bin: 01100011, oct: 143, character: c, oct:143.ok
ccodepoint: 64, bin:1100100, oct:144, utf8: 64, bin: 01100100, oct: 144, character: d, oct:144.ok
dcodepoint: 65, bin:1100101, oct:145, utf8: 65, bin: 01100101, oct: 145, character: e, oct:145.ok
ecodepoint: 66, bin:1100110, oct:146, utf8: 66, bin: 01100110, oct: 146, character: f, oct:146.ok
fcodepoint: 67, bin:1100111, oct:147, utf8: 67, bin: 01100111, oct: 147, character: g, oct:147.ok
gcodepoint: 68, bin:1101000, oct:150, utf8: 68, bin: 01101000, oct: 150, character: h, oct:150.ok
hcodepoint: 69, bin:1101001, oct:151, utf8: 69, bin: 01101001, oct: 151, character: i, oct:151.ok
icodepoint: 6a, bin:1101010, oct:152, utf8: 6a, bin: 01101010, oct: 152, character: j, oct:152.ok
jcodepoint: 6b, bin:1101011, oct:153, utf8: 6b, bin: 01101011, oct: 153, character: k, oct:153.ok
kcodepoint: 6c, bin:1101100, oct:154, utf8: 6c, bin: 01101100, oct: 154, character: l, oct:154.ok
lcodepoint: 6d, bin:1101101, oct:155, utf8: 6d, bin: 01101101, oct: 155, character: m, oct:155.ok
mcodepoint: 6e, bin:1101110, oct:156, utf8: 6e, bin: 01101110, oct: 156, character: n, oct:156.ok
ncodepoint: 6f, bin:1101111, oct:157, utf8: 6f, bin: 01101111, oct: 157, character: o, oct:157.ok
ocodepoint: 70, bin:1110000, oct:160, utf8: 70, bin: 01110000, oct: 160, character: p, oct:160.ok
pcodepoint: 71, bin:1110001, oct:161, utf8: 71, bin: 01110001, oct: 161, character: q, oct:161.ok
qcodepoint: 72, bin:1110010, oct:162, utf8: 72, bin: 01110010, oct: 162, character: r, oct:162.ok
rcodepoint: 73, bin:1110011, oct:163, utf8: 73, bin: 01110011, oct: 163, character: s, oct:163.ok
scodepoint: 74, bin:1110100, oct:164, utf8: 74, bin: 01110100, oct: 164, character: t, oct:164.ok
tcodepoint: 75, bin:1110101, oct:165, utf8: 75, bin: 01110101, oct: 165, character: u, oct:165.ok
ucodepoint: 76, bin:1110110, oct:166, utf8: 76, bin: 01110110, oct: 166, character: v, oct:166.ok
vcodepoint: 77, bin:1110111, oct:167, utf8: 77, bin: 01110111, oct: 167, character: w, oct:167.ok
wcodepoint: 78, bin:1111000, oct:170, utf8: 78, bin: 01111000, oct: 170, character: x, oct:170.ok
xcodepoint: 79, bin:1111001, oct:171, utf8: 79, bin: 01111001, oct: 171, character: y, oct:171.ok
ycodepoint: 7a, bin:1111010, oct:172, utf8: 7a, bin: 01111010, oct: 172, character: z, oct:172.ok
zcodepoint: 7b, bin:1111011, oct:173, utf8: 7b, bin: 01111011, oct: 173, character: {, oct:173.ok
{codepoint: 7c, bin:1111100, oct:174, utf8: 7c, bin: 01111100, oct: 174, character: |, oct:174.ok
|codepoint: 7d, bin:1111101, oct:175, utf8: 7d, bin: 01111101, oct: 175, character: }, oct:175.ok
}codepoint: 7e, bin:1111110, oct:176, utf8: 7e, bin: 01111110, oct: 176, character: ~, oct:176.ok
~codepoint: 7f, bin:1111111, oct:177, utf8: 7f, bin: 01111111, oct: 177, character: , oct:177.ok

   80 --- utf8 characters ---         --- utf8 characters ---         
   c0 --- utf8 characters ---         --- utf8 characters ---         
  100 codepoint: 100, bin:1|00000000, oct:400, utf8: c480, bin: 11000100|10000000, oct: 304 200, character: Ā, oct:400.ok
Ācodepoint: 101, bin:1|00000001, oct:401, utf8: c481, bin: 11000100|10000001, oct: 304 201, character: ā, oct:401.ok
ācodepoint: 102, bin:1|00000010, oct:402, utf8: c482, bin: 11000100|10000010, oct: 304 202, character: Ă, oct:402.ok
Ăcodepoint: 103, bin:1|00000011, oct:403, utf8: c483, bin: 11000100|10000011, oct: 304 203, character: ă, oct:403.ok
ăcodepoint: 104, bin:1|00000100, oct:404, utf8: c484, bin: 11000100|10000100, oct: 304 204, character: Ą, oct:404.ok
Ącodepoint: 105, bin:1|00000101, oct:405, utf8: c485, bin: 11000100|10000101, oct: 304 205, character: ą, oct:405.ok
ącodepoint: 106, bin:1|00000110, oct:406, utf8: c486, bin: 11000100|10000110, oct: 304 206, character: Ć, oct:406.ok
Ćcodepoint: 107, bin:1|00000111, oct:407, utf8: c487, bin: 11000100|10000111, oct: 304 207, character: ć, oct:407.ok
ćcodepoint: 108, bin:1|00001000, oct:410, utf8: c488, bin: 11000100|10001000, oct: 304 210, character: Ĉ, oct:410.ok
Ĉcodepoint: 109, bin:1|00001001, oct:411, utf8: c489, bin: 11000100|10001001, oct: 304 211, character: ĉ, oct:411.ok
ĉcodepoint: 10a, bin:1|00001010, oct:412, utf8: c48a, bin: 11000100|10001010, oct: 304 212, character: Ċ, oct:412.ok
Ċcodepoint: 10b, bin:1|00001011, oct:413, utf8: c48b, bin: 11000100|10001011, oct: 304 213, character: ċ, oct:413.ok
ċcodepoint: 10c, bin:1|00001100, oct:414, utf8: c48c, bin: 11000100|10001100, oct: 304 214, character: Č, oct:414.ok
Čcodepoint: 10d, bin:1|00001101, oct:415, utf8: c48d, bin: 11000100|10001101, oct: 304 215, character: č, oct:415.ok

(rand listing, ressu way): “See: Million random digits, and with 100000 normal deviates”

$ newressu --rand
($ newressu —rand —lines 20000) uusi kirja (million random digits)
00000   21740 74236  10030 96443  36759 04464  58747 37667  07922 66268
00001   99862 71020  69433 55183  64025 97438  92129 73937  72822 33844
00002   76545 21348  33063 29012  53876 76367  86413 86899  93812 53817
00003   94712 80955  77486 27783  88612 68440  63783 97978  20988 89115
00004   38264 81894  60156 78756  26009 33327  30337 76975  42970 08361

00005   55134 53142  10337 87295  68364 34227  75590 28361  30064 35670
00006   80126 82035  43299 80528  14674 15824  39695 19717  84323 12724
00007   17076 32335  97429 45370  89619 39889  93682 71524  03591 24260
00008   95552 98612  32952 97786  49656 59528  23493 82771  52655 01349
00009   24498 14092  93957 02410  87710 91509  23687 77315  71790 16967
$ newressu --rand --cn
00000   丂褋 丂廉  丁蠑 七洵  丄浚 丁郱  丁诘 七曛  丂淘 丁跱
00001   丂坶 丁渲  丁衜 丄膨  丁紤 丄回  七鵍 丂暹  丂嫿 一簧
00002   丂剘 丂匇  一鴱 丂繱  一弹 丄俊  一諟 丂埠  一鿇 七玂
00003   丂谓 丄習  一鄑 丁韼  七绷 丄燉  七栳 丁漊  一擦 丄萊
00004   七崺 丁挨  丁氆 丁翸  七鋗 丂玏  丄瞔 丁毋  七穗 一儉

00005   一薰 丂晠  丁躔 丂髑  丂讲 七墠  丂諵 丁潜  七鷃 七潿
00006   丂嘮 丁旀  丂新 七陸  丁邎 丄燝  七梶 丄柺  丄塶 丁湋
00007   丁鿭 丂馝  丄蘑 一蒒  丄呶 七皯  七萹 丂薴  丁闷 一匭
00008   丄虃 丁厙  七峈 丁茂  丂滳 七貫  丂悑 丂瓶  丂嚧 一鬸
00009   一峚 丄举  七拝 七駐  丂醹 一鼗  一皶 七躄  丁鳓 一鎭

Tämä tulostaa million random digits materiaalin ressulla

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <time.h>

#include <sys/time.h>

#define DEBUG

double limit = 9;
unsigned char limits[20];

char *procname;

unsigned char ressu_clockbyte() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

int periods[1024];

void ressu_genbytes(int size, unsigned char *buffer) /* JariK 2013-2020 v 1.2 */
{
  int c, d, e, f, clockbytes = 0,
    count = 0, rndbits = 0;
  unsigned char byte, prevbyte;

  for(c = 0;c < 1024; c++) {
    periods[c] = 0;
  }
  
  f = 0;
  for(c = 0; c < 8 || c % 8 != 0 || clockbytes < 2000 || c < 48 || c < 80
      // || rndbits < 8*size || rndbits2 < 8*size
      ; c++) {
    for(d = 0; d < size; d++) { // rotate left + xor
      byte = ressu_clockbyte();
      if(d == 0)
	prevbyte = byte;
      e = buffer[d];
      e = ((e & 0x80) >> 7) | ((e & 0x7f) << 1);   // rotate left 1
      //e=((e&0xe0)>>5) | ((e&0x1f)<<3); // rotate left 3
      //e=((e&0xfe)>>1) | ((e&0x1)<<7);  // rotate right 1
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	rndbits++;
	periods[count]++;
	count = 0;
	prevbyte = byte;
      }
      count++;
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + buffer[d]) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    clockbytes += size;
  }
#ifdef DEBUG5
  fprintf(stderr,"\n");
  fprintf(stderr,"ressu3_genbytes:");
  fprintf(stderr," c %d", c);
  fprintf(stderr,", c%%8 %d", c % 8);
  fprintf(stderr,", clockbytes %d", clockbytes);
  fprintf(stderr,", 8*size %d", 8 * size);
  fprintf(stderr,", rndbits %d", rndbits);
#endif
}

#define RESSUCNT 65536
#define aRESSU_CLEAR 2

static unsigned char ressu_bytes[RESSUCNT];
static int ressu_byte = 999999999;
static int ressu_cnt = RESSUCNT;

int ressu_genbyte()
{
  if(ressu_byte >= ressu_cnt) {
#ifdef RESSU_CLEAR
    memset(ressu_bytes, 0, ressu_cnt);
#else
    if(ressu_byte == 999999999)
      memset(ressu_bytes, 0, ressu_cnt);
#endif
    ressu_genbytes(ressu_cnt, ressu_bytes);
    ressu_byte = 0;
  }
  return(ressu_bytes[ressu_byte++]);
}

int ressu_genbyte_limit(int limit)
{
  int c;
  
  while((c = ressu_genbyte()) >= (256 / limit) * limit);
  return(c % limit);
}

int ressu_genshort()
{
  return(ressu_genbyte() | ressu_genbyte() << 8);
}

int ressu_genshort_limit(int limit)
{
  int c;
  
  while((c = ressu_genshort()) >= (65536 / limit) * limit);
  return(c % limit);
}

unsigned int ressu_genint()
{
  return(ressu_genshort() | ressu_genshort() << 16);
}

unsigned int ressu_genint_limit(unsigned long limit)
{
  unsigned int c;
  
  while((c = ressu_genint()) >= (((unsigned int)65536 * 65536) / limit) * limit);
  return(c % limit);
}

void count_10(int len, unsigned char *buf, int offs, int count, double limit, int *ok)
{
  int d, e, count10[10];
  unsigned char *p;

  for(d = 0; d < 10; d++)
    count10[d] = 0;

  p = buf + offs;
  for(d = 0; d < len; d++) {
    count10[*p - '0']++;
    p++;
  }

  for(d = 0;d < 10; d++) {
    if(count10[d] > count)
      e = count10[d] - count;
    else
      e = count - count10[d];

    if((double)e / count * 100 > limit) {
#ifdef DEBUG4
      fprintf(stderr,"\n%d", d);
      fprintf(stderr,", c=%d", offs);
      fprintf(stderr,", count10=%d", count10[d]);
      fprintf(stderr,", d=%d", e);
      fprintf(stderr," diff%%=%f",(double) e / count * 100);
      fflush(stderr);
#endif
      *ok = 0;
      break;
    }
  }
}

void count_100(int len, unsigned char *buf, int offs, int count, double limit, int *ok)
{
  int d, e, count100[100];
  unsigned char *p;

  for(d = 0; d < 100; d++)
    count100[d] = 0;

  p = buf + offs;
  for(d = 0; d < len; d++) {
    count100[(*p - '0') * 10 + (*(p + 1) - '0')]++;
    p += 2;
  }

  for(d = 0; d < 10; d++) {
    if(count100[d] > count)
      e = count100[d] - count;
    else
      e = count - count100[d];

    if((double)e / count * 100 > limit) {
      fprintf(stderr,"\n%d", d);
      fprintf(stderr,", c=%d", offs);
      fprintf(stderr,", count100=%d", count100[d]);
      fprintf(stderr,", e=%d", e);
      fprintf(stderr," diff%%=%f",(double) e / count * 100);
      fflush(stderr);
      *ok = 0;
    }
  }
}

#include <stdarg.h>

#define DEBUG58

int stat_line_chars = 0;
int stat_line_edchars = 0;

void stat_line_begin()
{
#ifdef DEBUG58
  fprintf(stderr,"\n");
#else
  fprintf(stderr,"\r");
#endif  
  stat_line_edchars = stat_line_chars;
  stat_line_chars = 0;
}


void stat_line_printf(const unsigned char *format, ...)
{
  int count;
  va_list args;
  static unsigned char *stat_line_buf;
  static size_t stat_line_buf_length;

  va_start(args, format);
  count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;
  va_end(args);
  if(stat_line_buf_length < count) {
    stat_line_buf_length = count;
    stat_line_buf=realloc(stat_line_buf, stat_line_buf_length);
    va_start(args, format);
    count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;
    va_end(args);
  }
  fprintf(stderr,"%s", stat_line_buf);
  stat_line_chars += strlen(stat_line_buf);
}

void stat_line_end()
{
  int c, d;
  // previous line longer than this one,
  // overwrite with spaces
  if(stat_line_edchars > stat_line_chars) {
    d = stat_line_edchars - stat_line_chars;
    for(c = 0; c < d; c++) {
#ifdef DEBUG58
      fprintf(stderr,"*");
#else
      fprintf(stderr," ");
#endif
    }
    for(c = 0; c < d; c++)
      fprintf(stderr,"\b");
  }
  fflush(stderr);
}

#define KALA
#define aTRY 2

#define HTMLTIMEFORMAT "%a, %d %b %Y %H:%M:%S %Z"
#define TIMEFORMAT "%H:%M:%S %Z"
#define TIMEFORMAT2 "%a, %H:%M:%S %Z"
#define DATEFORMAT "%a, %d %b %Y"

void main(int argc,char *argv[])
{
  unsigned int c, d, e;
  long int start, now;
  unsigned char *digits, *p;
  unsigned char filename[128];
  
  FILE *fp1;
  
  procname = argv[0];

  limit = 9;
  if(argc > 1)
    limit = atof(argv[1]);
  sprintf(limits,"%f", limit);
  fprintf(stderr,"Limit: %s\n", limits);
  
  if((digits = malloc(1000001)) == NULL) {
    fprintf(stderr,"%s: cannot allocate memory", procname);
  }

#ifdef KALA
  sprintf(filename,"ressupdf%s.dat", limits);
  if((fp1 = fopen(filename, "r")) != NULL) {
    fgets(digits, 1000001, fp1);
    fclose(fp1);
  } else {
#endif
    int ok = 0;
    while(!ok) {
      p = digits;
      start = time(NULL);
      for(c = 0; c < 1000000; c += 2500) {
	now = time(NULL);
	stat_line_begin();
	stat_line_printf("\rblk: %d", c/2500);
	stat_line_printf(", pos: %d", c);

	if(c > 0) {
	  int secondsleft = (int)((((double)now - start) / c) * (1000000 - c));
	  int temp, timeprinted = 0;
	  stat_line_printf(", left");
	  
	  temp = secondsleft / (24 * 3600);
	  if(temp > 0) {
	    timeprinted = 1;
	    stat_line_printf(" %d days", temp);
	    secondsleft -= temp * (24 * 3600);
	  }
	  temp = secondsleft / 3600;
	  if(temp > 0) {
	    timeprinted = 1;
	    stat_line_printf(" %d hours", temp);
	    secondsleft -= temp * 3600;
	  }
	  temp = secondsleft / 60;
	  if(temp > 0) {
	    timeprinted = 1;
	    stat_line_printf(" %d minutes", temp);
	    secondsleft -= temp * 60;
	  }
	  temp = secondsleft;
	  if(!timeprinted) {
	    stat_line_printf(" %d seconds", temp);
	  }
	  long int secondsend = (int)start + ((((double)now - start) / c) * 1000000);
	  char timebuf[128], timebuf2[128];
	  stat_line_printf(", ready at");
	  strftime(timebuf, sizeof(timebuf), DATEFORMAT,
		   localtime((time_t *) &secondsend));
	  strftime(timebuf2, sizeof(timebuf2), DATEFORMAT,
		   localtime((time_t *) &now));
	  if(strcmp(timebuf, timebuf2)) {
	    stat_line_printf(" %s", timebuf);
	  }
	  strftime(timebuf, sizeof(timebuf), TIMEFORMAT,
		   localtime((time_t *) &secondsend));
	  stat_line_printf(" %s", timebuf);
	  strftime(timebuf, sizeof(timebuf), TIMEFORMAT2,
		   localtime((time_t *) &now));
	  stat_line_printf("(now %s)", timebuf);
	}
	stat_line_end();
	ok = 0;
	while(!ok) {
#ifdef TRY
	  p = digits + c;
	  for(d = 0; d < 250; d++) {
	    *p++='0'; *p++='1'; *p++='2'; *p++='3';
	    *p++='4'; *p++='5'; *p++='6'; *p++='7';
	    *p++='8'; *p++='9';
	  }
	  
	  int f = 0;
	  p = digits + c;
	  for(d = 0; d < 2500; d++) {
	    f = (f + ressu_genshort_limit(2500)) % 2500;
	    e = p[d];
	    p[d] = p[f];
	    p[f] = e;
	  }
#else
	  p = digits + c;
	  for(d = 0; d < 2500; d++) {
	    *p++ = ressu_genbyte_limit(10) + '0';
	  }
#endif
	  ok = 1;
	  count_10(2500, digits, c, 250, limit, &ok);
	  //count_10(2500, digits, c, 250, 2.5, &ok);
	} // while(!ok
      } // for(c=0;
      *p ='\0';

      ok = 1;
      //count_10(1000000, digits, 0, 100000, 3.5, &ok);
      // count_100(500000, digits, 0, 5000, 3.5, &ok);
      //count_100(500000, digits, 0, 5000, 2.5, &ok);

      stat_line_begin();
      stat_line_printf("\rblk: %d",c / 2500);
      stat_line_printf(", pos: %d, done.", c);
      stat_line_end();
      fprintf(stderr,"\n");
    } // while(!ok)
#ifdef KALA
    sprintf(filename,"ressupdf%s.dat", limits);
    if((fp1 = fopen(filename, "w")) != NULL) {
      fputs(digits, fp1);
      fclose(fp1);
    }
  }
#endif

  p = digits;
  for(c = 0; c < 20000; c++) {
    if(c % 50 == 0) {
      fprintf(stdout,"%20s", "");
      fprintf(stdout,"%-20s", "RESSU RANDOM BITS");
      fprintf(stdout,"%20s", "");
      fprintf(stdout,"%11d", c / 50 + 1);
      fprintf(stdout,"\n\n");
    } else if(c % 5 == 0) {
      fprintf(stdout,"\n");
    }
    fprintf(stdout,"%05d", c);
    fprintf(stdout," ");
    for(d = 0; d < 5; d++) {
      fprintf(stdout,"  ");
      for(e=0;e<5;e++)
	fprintf(stdout,"%c", *p++);
      fprintf(stdout," ");
      for(e = 0; e < 5; e++)
	fprintf(stdout,"%c", *p++);
    }
    fprintf(stdout,"\n");
  }
}

Printout:

...
                    RESSU RANDOM BITS                                 2

00050   17742 90978  20327 99793  09894 83023  24240 04809  02397 57605
00051   69731 00724  79328 16357  42844 64199  58819 42893  04156 30047
00052   24572 77596  88519 44700  50806 16297  94987 10761  07043 80638
00053   69962 81888  72976 01358  42459 68683  78899 39340  11999 13284
00054   54542 84683  51941 09434  30594 35535  35814 43101  47387 78591

00055   01750 72686  05907 24473  54501 94416  38862 90650  82982 60288
00056   61300 71065  13214 47645  14431 55466  42331 76349  64840 76355
00057   16065 02085  18175 94643  19271 73959  67609 13699  52113 87491
00058   53317 49643  28677 63486  50574 83719  02169 71535  52186 94945
00059   09805 93912  06726 48683  71397 26752  69332 97877  75471 12043

00060   32509 79800  94963 98307  20909 55905  45092 16663  40666 71118
00061   69566 50136  56766 14661  66668 18376  70231 88838  15166 98110
00062   14306 75279  70432 18240  57800 84134  89759 93733  99649 67792
00063   98841 27596  72336 68936  80330 58378  40111 29362  71717 97984
00064   97438 00397  68367 14379  73854 66167  83473 57904  65723 89246

00065   85757 80797  97117 31751  34814 73303  32275 10252  43687 99186
00066   01301 91011  23578 98576  70204 72462  07013 75523  25481 82102
00067   15434 82659  01554 99856  69543 62445  59721 71282  54068 79247
00068   22366 89681  96308 83960  85382 86605  52183 60856  28081 89425
00069   22548 46969  99594 98343  76579 53245  11516 29313  82536 12261

00070   94099 33155  61371 40590  94751 95390  14484 42212  33870 54040
00071   42073 36389  32803 81890  99328 05960  69418 40568  05591 37183
00072   56946 95764  81191 75005  57238 22658  88628 60884  34721 89120
00073   55423 71707  53515 64023  38182 98412  49163 72441  40175 94841
00074   65736 76047  00426 33814  54279 53012  28756 30077  07304 98110

00075   09975 26885  56587 79319  21111 45568  48821 71858  17419 81809
00076   40989 23782  61300 05131  09654 70146  17527 89776  15083 25525
00077   59502 62459  25865 64290  03791 00902  99654 11047  81028 88697
00078   05911 04417  51850 72237  52924 16709  08528 59122  08090 74950
00079   56707 69992  63538 51049  56414 19722  89973 20718  74092 99756

00080   54761 78783  64511 08489  12059 86522  76650 18753  96548 63488
00081   38502 77610  16498 75110  76846 77545  35529 80274  95536 51291
00082   90171 42638  84352 04269  09133 61636  28115 15471  79874 11649
00083   11396 17063  36477 85175  25267 22793  21376 44996  96616 89233
00084   69149 11776  86056 67806  55529 61713  66028 67571  98188 41957

00085   24620 39702  16363 91952  41532 50804  75205 90986  91060 60663
00086   72905 04521  25448 42824  63464 84321  35445 44154  75242 64517
00087   56282 64892  22474 62633  04941 31364  86882 69973  47361 99146
00088   45349 43405  72289 36148  62758 78365  98873 00722  30598 08620
00089   01388 94749  42439 12958  85192 84018  99461 61367  58575 34130

00090   09402 98084  06255 33480  73435 96183  32346 98552  12425 61651
00091   16196 52241  79554 05184  16176 26149  45204 84321  34076 01033
00092   41376 62183  69497 26396  59490 67839  68194 69435  78057 75337
00093   06816 97357  81606 83265  73652 54869  06504 83737  86270 07765
00094   50336 28597  83445 25111  84782 13507  84907 17025  76320 91352

00095   20878 07006  67793 45175  75975 44617  82764 89124  34061 79955
00096   79920 60145  89200 09256  96383 91519  60603 68168  16011 38572
00097   48244 92365  82713 12384  23602 80116  95662 88142  19606 84202
00098   13455 21525  93409 51728  15764 63568  00612 90243  90778 99042
00099   77433 99809  25327 34560  70120 78586  27165 29579  60124 14500
                    RESSU RANDOM BITS                                 3

00100   98225 94921  37093 56968  81200 60112  31201 67388  80992 72445
00101   55681 22490  70683 07715  97102 38508  13787 10500  04785 57383
00102   64624 57524  67608 90944  13863 58712  82638 55760  46560 77855
00103   42276 34624  73319 60353  81043 80593  29831 01067  62128 71385
00104   52641 48563  35066 13659  49948 69243  83099 86151  81455 25561

00105   43407 53921  98946 54240  70753 08464  73282 01982  48276 03921
00106   54577 09657  32778 47794  19627 58791  11679 09479  57297 11075
00107   76619 43447  04417 11921  14858 32489  01024 26846  82457 39669
00108   48399 62589  90681 76259  04405 32977  35462 35641  77427 47811
00109   45223 67943  03521 12482  55595 21037  67109 62208  42512 13150

00110   33620 25141  23653 09332  03284 09797  37987 45675  76920 33935
00111   32306 56053  24435 59821  15476 69657  64606 57528  04364 35402
00112   53100 91082  46382 88271  55521 52981  59009 46366  56773 03251
00113   92113 18616  31236 45997  75651 26459  89519 54780  87788 12855
00114   47788 83993  13664 19450  46126 81687  34224 26786  13330 36140

00115   62958 16807  79203 26843  26604 66234  29717 70317  61712 46439
00116   96909 22031  38002 64294  22698 33377  73011 32717  08886 00711
00117   47356 07381  07805 42091  70442 75838  81204 33079  43998 06378
00118   14028 43141  18516 85420  44282 49146  36400 14280  39400 07228
00119   49580 47869  02330 32465  75317 06413  01007 06898  42200 95453

00120   02985 67968  18045 03364  04061 23882  11353 63530  09178 39509
00121   03273 96065  47529 34749  63066 38374  05455 62346  11741 94157
00122   23385 92695  52738 25218  89620 76213  58440 91996  64772 12959
00123   90823 27995  07090 88421  54961 37736  37467 58044  71799 64360
00124   33887 85780  06317 78914  82704 18361  29095 27681  56330 34108

00125   75056 67546  10567 77241  67072 91487  93011 55737  20964 94703
00126   05489 80439  22228 23922  53525 46958  29892 10707  75548 49477
00127   44613 65998  68249 47336  48552 31708  32719 87201  55409 10564
00128   50068 95097  73236 41950  71834 33839  41452 24690  23847 75012
00129   07507 12156  77054 46383  20390 83765  08003 26405  34018 52247

00130   07870 76399  89979 71327  28740 37314  95754 59355  91496 88323
00131   56394 06551  67546 59950  40968 98397  73401 98309  29766 18729
00132   42481 08526  28716 68598  53228 71142  14448 59721  18361 44639
00133   59275 01370  36775 89748  23930 39536  85232 74208  32793 62803
00134   35616 27137  11079 94080  03589 13286  16881 16298  87820 83679

00135   73497 73109  30111 34058  28022 89290  45635 88020  41070 40721
00136   50527 34038  00823 99594  65641 48184  73083 96977  61989 82760
00137   72261 19301  99253 64192  89296 35525  46338 20033  88519 18643
00138   74078 30979  14259 71378  77923 50563  45619 09479  41882 60785
00139   92291 56636  81071 75996  82077 49803  20786 97042  57848 27400

00140   10657 61863  97054 29344  80492 63211  85994 01135  12742 95135
00141   61544 11709  50756 98947  36027 50318  22992 62246  04572 05310
00142   58304 90967  98064 13575  95892 36013  85527 76628  80363 65409
00143   60626 87624  78003 10446  31401 15903  51764 23838  90002 24421
00144   18686 07635  47573 18678  28796 22120  76601 16788  17529 40289

00145   77639 58662  47179 24199  08996 95207  83586 64483  83746 82002
00146   45361 55716  45661 11221  32186 36359  00273 47492  76060 84107
00147   60461 94122  98441 98217  20483 51905  53098 62933  18505 27967
00148   48343 23724  90306 68422  75352 48267  14368 52626  92610 23465
00149   22905 85298  54833 10053  67728 19154  05224 87915  24816 20958
                    RESSU RANDOM BITS                                 4
...

Debug:

...
blk: 123, pos: 307500, left 0 seconds, ready at 00:20:48 EEST(now Mon, 00:20:48 EEST)

blk: 124, pos: 310000, left 0 seconds, ready at 00:20:48 EEST(now Mon, 00:20:48 EEST)

blk: 125, pos: 312500, left 0 seconds, ready at 00:20:48 EEST(now Mon, 00:20:48 EEST)

blk: 126, pos: 315000, left 0 seconds, ready at 00:20:48 EEST(now Mon, 00:20:48 EEST)

blk: 127, pos: 317500, left 0 seconds, ready at 00:20:48 EEST(now Mon, 00:20:48 EEST)

blk: 128, pos: 320000, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 129, pos: 322500, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 130, pos: 325000, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 131, pos: 327500, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 132, pos: 330000, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 133, pos: 332500, left 2 seconds, ready at 00:20:51 EEST(now Mon, 00:20:49 EEST)

blk: 134, pos: 335000, left 1 seconds, ready at 00:20:50 EEST(now Mon, 00:20:49 EEST)

blk: 135, pos: 337500, left 1 seconds, ready at 00:20:50 EEST(now Mon, 00:20:49 EEST)

blk: 136, pos: 340000, left 1 seconds, ready at 00:20:50 EEST(now Mon, 00:20:49 EEST)

blk: 137, pos: 342500, left 1 seconds, ready at 00:20:50 EEST(now Mon, 00:20:49 EEST)

...

(just a plain old ressu): cn:

$ newressu —cn
00000 狥鶇蝢擪懕夝侾毮貣迶餖僆緣崾凷桼沁赇喉潣絢霂燌雷飫爤鏓诎翦羷噃叄
00001 鶺鼂褯驻嵩后佤齚瓨同骗涝鐔畊忊鄞篑扯寋圈蕟楁队斁牘吾莔碦囘频枭吲
00002 鏑豈塟鬊燬彔麗鯂絩襻鄝侢傮敦狤淈媉日鷲埡礦塡粱貗蹚翲翂耡狣言婨朩
00003 立臕籗铊笝蟍濓鹗酫鏟讫低瀍閴缐簁捒紜舼琤靄嘁镍墊鋈顨鎼亸壠愖昨瀧
00004 嗞鹶虦挳擄裕繌卛喃幼簡仞璊出鱽垶撟挎阢穒馁訷倧嬶魮瓑含堸鷵犽澯聤
00005 犩解珎索潎豉猠捜伻藮麮播馦镒走翙失殺钲壅鮹黌凧訚据簢敽櫀童神箎車
00006 販炦鉒蟝攸僺轺鷍霝塲穁腲栈丯牉駜邪秝粄猳鎤贏恏騣經鵩姸苎蓔蚢藶禸
00007 昇鲾鋤璤攫粽自暖铘鿒襤兢蟭糸桚壛碄膨荋夤窞璒禗瞻寤跧橎默五袎蜵綗
00008 埵龱鶫閸霹譠愽駆秓誃挪筯蓀菻潮顃诤屮赬掮媚菋蔞綨枏櫶絜軯梊醰葑獴
00009 峵澾蹰騫晳妫羾熟惉兽萌悮彛趬杩吣鵁殍跪缈浟醛雵朡堄蜺儜臦灛鉿樈翈

jp1

$ newressu —jp1
00000 ほづみゕにゕぼかざくがよどどごぴゅれにだらたぃぢせゐゆだはゔもを
00001 そろきおべうかへぅよこあねゅづぐけぴうぼねひげぎゎょぞぬりそぜゃ
00002 ばくろゆゅうょすじごけぃげすうづほかぜぐつぇゅぢぼびにぇでゔがぴ
00003 ゐればぜずざれめさむめしごばゐぶんそゔそでびばよこでゑべなぎりん
00004 ぢりぁいぷっゕりぅゆにねだぅねもぷつゕろっぬぃゐぺぅょはどとけゎ
00005 ずゎべほずづなわゅさゑわぢとまざゎをぎゎぐそっぴやぴしちゕぼぇぷ
00006 ぼぱへぽぅふょぽづわぼぐずとじきほぇぽすめどわとぞきぞすあぉどれ
00007 ぇをきぷうさうきうひょぅうづぬむりうしだはゆぃぃゐほぉぴぞつずの
00008 そりきさぴなろじぬぷびたゎゃがにぁれむっしまばぞゃじぴぃこぇいあ
00009 ぱるぷがさふごみぞゑうくけばっおかくきべだひぬえびへまそびにまほ

jp2

$ newressu —jp2
00000 エヿリニヷワデブモネドャヤヾヤヹヱツヹカゲギカザコデポゲヂストヹ
00001 トビヶバツツアフコホャプゴァサスビネペホヤキヒヿギモヴボヹサカズ
00002 ゼァゥャヺャヵカカ・ヶボクゼヱアドヹミヨヨムヂェホガヿイゾヾヂジ
00003 デボキホョメクラドムウドソヸモレシジヷゥヤフエハウュゴヴヵゴーェ
00004 セポコゴマ・ュアョキフウラヒバヰカギエダャブシンムメヲヨヾピベヅ
00005 ガヲポノフリヮヂヱメヂマヶアデプエトィヌヌタシヴョパヴボゴーテモ
00006 ヨェカバズカヸヒソザャキチプバズチプチチヴパスヤトフヶヅチセエウ
00007 ヴゥノタケキセ゠ト゠ウペトキィァベネナヂチパィゾカヾテヲペロヾヤ
00008 フヲネユマグサヮシヾケヘワヷビヨミゴセ゠オヸリヹズモプヾダウガヂ
00009 ・ギェヲヴポギポワゾゼハナグリ゠ズアペトレゲタノャトバダユミヒヸ

jp3

utf-8 ohjelman käyttöä:

$ ./utf-8 | head -n 20
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
    0 --- control characters ---       !"#$%&'()*+,-./0123456789:;<=>?
   40 @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
   80 --- utf8 characters ---         --- utf8 characters ---         
   c0 --- utf8 characters ---         --- utf8 characters ---         
  100 ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿ
  140 ŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ
  180 ƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿ
  1c0 ǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿ
  200 ȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿ
  240 ɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ
  280 ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿ
  2c0 ˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦˧˨˩˪˫ˬ˭ˮ˯˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾˿
  300 ̀́̂̃̄̅̆̇̈̉
  340 ͇͈͉̀́͂̓̈́͆ͅͰͱͲͳʹ͵Ͷͷ͸͹ͺͻͼͽ;Ϳ
  380 ΀΁΂΃΄΅Ά·ΈΉΊ΋Ό΍ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξο
  3c0 πρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿ
  400 ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп
$ utf-8 | grep 4000
 4000 䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿
14000 𔀀𔀁𔀂𔀃𔀄𔀅𔀆𔀇𔀈𔀉𔀊𔀋𔀌𔀍𔀎𔀏𔀐𔀑𔀒𔀓𔀔𔀕𔀖𔀗𔀘𔀙𔀚𔀛𔀜𔀝𔀞𔀟𔀠𔀡𔀢𔀣𔀤𔀥𔀦𔀧𔀨𔀩𔀪𔀫𔀬𔀭𔀮𔀯𔀰𔀱𔀲𔀳𔀴𔀵𔀶𔀷𔀸𔀹𔀺𔀻𔀼𔀽𔀾𔀿
24000 𤀀𤀁𤀂𤀃𤀄𤀅𤀆𤀇𤀈𤀉𤀊𤀋𤀌𤀍𤀎𤀏𤀐𤀑𤀒𤀓𤀔𤀕𤀖𤀗𤀘𤀙𤀚𤀛𤀜𤀝𤀞𤀟𤀠𤀡𤀢𤀣𤀤𤀥𤀦𤀧𤀨𤀩𤀪𤀫𤀬𤀭𤀮𤀯𤀰𤀱𤀲𤀳𤀴𤀵𤀶𤀷𤀸𤀹𤀺𤀻𤀼𤀽𤀾𤀿
34000 𴀀𴀁𴀂𴀃𴀄𴀅𴀆𴀇𴀈𴀉𴀊𴀋𴀌𴀍𴀎𴀏𴀐𴀑𴀒𴀓𴀔𴀕𴀖𴀗𴀘𴀙𴀚𴀛𴀜𴀝𴀞𴀟𴀠𴀡𴀢𴀣𴀤𴀥𴀦𴀧𴀨𴀩𴀪𴀫𴀬𴀭𴀮𴀯𴀰𴀱𴀲𴀳𴀴𴀵𴀶𴀷𴀸𴀹𴀺𴀻𴀼𴀽𴀾𴀿
$ utf-8 | grep  4000
 4000 䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿
14000 𔀀𔀁𔀂𔀃𔀄𔀅𔀆𔀇𔀈𔀉𔀊𔀋𔀌𔀍𔀎𔀏𔀐𔀑𔀒𔀓𔀔𔀕𔀖𔀗𔀘𔀙𔀚𔀛𔀜𔀝𔀞𔀟𔀠𔀡𔀢𔀣𔀤𔀥𔀦𔀧𔀨𔀩𔀪𔀫𔀬𔀭𔀮𔀯𔀰𔀱𔀲𔀳𔀴𔀵𔀶𔀷𔀸𔀹𔀺𔀻𔀼𔀽𔀾𔀿
24000 𤀀𤀁𤀂𤀃𤀄𤀅𤀆𤀇𤀈𤀉𤀊𤀋𤀌𤀍𤀎𤀏𤀐𤀑𤀒𤀓𤀔𤀕𤀖𤀗𤀘𤀙𤀚𤀛𤀜𤀝𤀞𤀟𤀠𤀡𤀢𤀣𤀤𤀥𤀦𤀧𤀨𤀩𤀪𤀫𤀬𤀭𤀮𤀯𤀰𤀱𤀲𤀳𤀴𤀵𤀶𤀷𤀸𤀹𤀺𤀻𤀼𤀽𤀾𤀿
34000 𴀀𴀁𴀂𴀃𴀄𴀅𴀆𴀇𴀈𴀉𴀊𴀋𴀌𴀍𴀎𴀏𴀐𴀑𴀒𴀓𴀔𴀕𴀖𴀗𴀘𴀙𴀚𴀛𴀜𴀝𴀞𴀟𴀠𴀡𴀢𴀣𴀤𴀥𴀦𴀧𴀨𴀩𴀪𴀫𴀬𴀭𴀮𴀯𴀰𴀱𴀲𴀳𴀴𴀵𴀶𴀷𴀸𴀹𴀺𴀻𴀼𴀽𴀾𴀿
$ utf-8 | grep " 4000"
 4000 䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿
$ utf-8 | grep "1f3"
1f300 🌀🌁🌂🌃🌄🌅🌆🌇🌈🌉🌊🌋🌌🌍🌎🌏🌐🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜🌝🌞🌟🌠🌡🌢🌣🌤🌥🌦🌧🌨🌩🌪🌫🌬🌭🌮🌯🌰🌱🌲🌳🌴🌵🌶🌷🌸🌹🌺🌻🌼🌽🌾🌿
1f340 🍀🍁🍂🍃🍄🍅🍆🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍔🍕🍖🍗🍘🍙🍚🍛🍜🍝🍞🍟🍠🍡🍢🍣🍤🍥🍦🍧🍨🍩🍪🍫🍬🍭🍮🍯🍰🍱🍲🍳🍴🍵🍶🍷🍸🍹🍺🍻🍼🍽🍾🍿
1f380 🎀🎁🎂🎃🎄🎅🎆🎇🎈🎉🎊🎋🎌🎍🎎🎏🎐🎑🎒🎓🎔🎕🎖🎗🎘🎙🎚🎛🎜🎝🎞🎟🎠🎡🎢🎣🎤🎥🎦🎧🎨🎩🎪🎫🎬🎭🎮🎯🎰🎱🎲🎳🎴🎵🎶🎷🎸🎹🎺🎻🎼🎽🎾🎿
1f3c0 🏀🏁🏂🏃🏄🏅🏆🏇🏈🏉🏊🏋🏌🏍🏎🏏🏐🏑🏒🏓🏔🏕🏖🏗🏘🏙🏚🏛🏜🏝🏞🏟🏠🏡🏢🏣🏤🏥🏦🏧🏨🏩🏪🏫🏬🏭🏮🏯🏰🏱🏲🏳🏴🏵🏶🏷🏸🏹🏺🏻🏼🏽🏾🏿
$ utf-8 | grep "1f4"
 1f40 ὀὁὂὃὄὅ὆὇ὈὉὊὋὌὍ὎὏ὐὑὒὓὔὕὖὗ὘Ὑ὚Ὓ὜Ὕ὞ὟὠὡὢὣὤὥὦὧὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώ὾὿
11f40 𑽀𑽁𑽂𑽃𑽄𑽅𑽆𑽇𑽈𑽉𑽊𑽋𑽌𑽍𑽎𑽏𑽐𑽑𑽒𑽓𑽔𑽕𑽖𑽗𑽘𑽙𑽚𑽛𑽜𑽝𑽞𑽟𑽠𑽡𑽢𑽣𑽤𑽥𑽦𑽧𑽨𑽩𑽪𑽫𑽬𑽭𑽮𑽯𑽰𑽱𑽲𑽳𑽴𑽵𑽶𑽷𑽸𑽹𑽺𑽻𑽼𑽽𑽾𑽿
1f400 🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿
1f440 👀👁👂👃👄👅👆👇👈👉👊👋👌👍👎👏👐👑👒👓👔👕👖👗👘👙👚👛👜👝👞👟👠👡👢👣👤👥👦👧👨👩👪👫👬👭👮👯👰👱👲👳👴👵👶👷👸👹👺👻👼👽👾👿
1f480 💀💁💂💃💄💅💆💇💈💉💊💋💌💍💎💏💐💑💒💓💔💕💖💗💘💙💚💛💜💝💞💟💠💡💢💣💤💥💦💧💨💩💪💫💬💭💮💯💰💱💲💳💴💵💶💷💸💹💺💻💼💽💾💿
1f4c0 📀📁📂📃📄📅📆📇📈📉📊📋📌📍📎📏📐📑📒📓📔📕📖📗📘📙📚📛📜📝📞📟📠📡📢📣📤📥📦📧📨📩📪📫📬📭📮📯📰📱📲📳📴📵📶📷📸📹📺📻📼📽📾📿
21f40 𡽀𡽁𡽂𡽃𡽄𡽅𡽆𡽇𡽈𡽉𡽊𡽋𡽌𡽍𡽎𡽏𡽐𡽑𡽒𡽓𡽔𡽕𡽖𡽗𡽘𡽙𡽚𡽛𡽜𡽝𡽞𡽟𡽠𡽡𡽢𡽣𡽤𡽥𡽦𡽧𡽨𡽩𡽪𡽫𡽬𡽭𡽮𡽯𡽰𡽱𡽲𡽳𡽴𡽵𡽶𡽷𡽸𡽹𡽺𡽻𡽼𡽽𡽾𡽿
31f40 𱽀𱽁𱽂𱽃𱽄𱽅𱽆𱽇𱽈𱽉𱽊𱽋𱽌𱽍𱽎𱽏𱽐𱽑𱽒𱽓𱽔𱽕𱽖𱽗𱽘𱽙𱽚𱽛𱽜𱽝𱽞𱽟𱽠𱽡𱽢𱽣𱽤𱽥𱽦𱽧𱽨𱽩𱽪𱽫𱽬𱽭𱽮𱽯𱽰𱽱𱽲𱽳𱽴𱽵𱽶𱽷𱽸𱽹𱽺𱽻𱽼𱽽𱽾𱽿

$ ./utf-8 --startcp 0x2800 --endcp0x2900
startcp=2800(0x2800)
endcp=2900(0x2900)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================

 2800 ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿
 2840 ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿
 2880 ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿
 28c0 ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿
$ ./utf-8 --startcp 0xac00 --endcp 0xd7a3
startcp=ac00(0xac00)
endcp=d7a3(0xd7a3)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================

 ac00 가각갂갃간갅갆갇갈갉갊갋갌갍갎갏감갑값갓갔강갖갗갘같갚갛개객갞갟갠갡갢갣갤갥갦갧갨갩갪갫갬갭갮갯갰갱갲갳갴갵갶갷갸갹갺갻갼갽갾갿
 ac40 걀걁걂걃걄걅걆걇걈걉걊걋걌걍걎걏걐걑걒걓걔걕걖걗걘걙걚걛걜걝걞걟걠걡걢걣걤걥걦걧걨걩걪걫걬걭걮걯거걱걲걳건걵걶걷걸걹걺걻걼걽걾걿
 ac80 검겁겂것겄겅겆겇겈겉겊겋게겍겎겏겐겑겒겓겔겕겖겗겘겙겚겛겜겝겞겟겠겡겢겣겤겥겦겧겨격겪겫견겭겮겯결겱겲겳겴겵겶겷겸겹겺겻겼경겾겿
 acc0 곀곁곂곃계곅곆곇곈곉곊곋곌곍곎곏곐곑곒곓곔곕곖곗곘곙곚곛곜곝곞곟고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻과곽곾곿
 ad00 관괁괂괃괄괅괆괇괈괉괊괋괌괍괎괏괐광괒괓괔괕괖괗괘괙괚괛괜괝괞괟괠괡괢괣괤괥괦괧괨괩괪괫괬괭괮괯괰괱괲괳괴괵괶괷괸괹괺괻괼괽괾괿
 ad40 굀굁굂굃굄굅굆굇굈굉굊굋굌굍굎굏교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟굠굡굢굣굤굥굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿
 ad80 궀궁궂궃궄궅궆궇궈궉궊궋권궍궎궏궐궑궒궓궔궕궖궗궘궙궚궛궜궝궞궟궠궡궢궣궤궥궦궧궨궩궪궫궬궭궮궯궰궱궲궳궴궵궶궷궸궹궺궻궼궽궾궿
 adc0 귀귁귂귃귄귅귆귇귈귉귊귋귌귍귎귏귐귑귒귓귔귕귖귗귘귙귚귛규귝귞귟균귡귢귣귤귥귦귧귨귩귪귫귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿
 ae00 글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓긔긕긖긗긘긙긚긛긜긝긞긟긠긡긢긣긤긥긦긧긨긩긪긫긬긭긮긯기긱긲긳긴긵긶긷길긹긺긻긼긽긾긿
 ...
 d580 햀햁햂햃햄햅햆햇했행햊햋햌햍햎햏햐햑햒햓햔햕햖햗햘햙햚햛햜햝햞햟햠햡햢햣햤향햦햧햨햩햪햫햬햭햮햯햰햱햲햳햴햵햶햷햸햹햺햻햼햽햾햿
 d5c0 헀헁헂헃헄헅헆헇허헉헊헋헌헍헎헏헐헑헒헓헔헕헖헗험헙헚헛헜헝헞헟헠헡헢헣헤헥헦헧헨헩헪헫헬헭헮헯헰헱헲헳헴헵헶헷헸헹헺헻헼헽헾헿
 d600 혀혁혂혃현혅혆혇혈혉혊혋혌혍혎혏혐협혒혓혔형혖혗혘혙혚혛혜혝혞혟혠혡혢혣혤혥혦혧혨혩혪혫혬혭혮혯혰혱혲혳혴혵혶혷호혹혺혻혼혽혾혿
 d640 홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓화확홖홗환홙홚홛활홝홞홟홠홡홢홣홤홥홦홧홨황홪홫홬홭홮홯홰홱홲홳홴홵홶홷홸홹홺홻홼홽홾홿
 d680 횀횁횂횃횄횅횆횇횈횉횊횋회획횎횏횐횑횒횓횔횕횖횗횘횙횚횛횜횝횞횟횠횡횢횣횤횥횦횧효횩횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿
 d6c0 훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛훜훝훞훟훠훡훢훣훤훥훦훧훨훩훪훫훬훭훮훯훰훱훲훳훴훵훶훷훸훹훺훻훼훽훾훿
 d700 휀휁휂휃휄휅휆휇휈휉휊휋휌휍휎휏휐휑휒휓휔휕휖휗휘휙휚휛휜휝휞휟휠휡휢휣휤휥휦휧휨휩휪휫휬휭휮휯휰휱휲휳휴휵휶휷휸휹휺휻휼휽휾휿
 d740 흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟흠흡흢흣흤흥흦흧흨흩흪흫희흭흮흯흰흱흲흳흴흵흶흷흸흹흺흻흼흽흾흿
 d780 힀힁힂힃힄힅힆힇히힉힊힋힌힍힎힏힐힑힒힓힔힕힖힗힘힙힚힛힜힝힞힟힠힡힢
$ ./utf-8 --startcp 0x1100 --endcp 0x11ff
startcp=1100(0x1100)
endcp=11ff(0x11ff)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================

 1100 ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑᄒᄓᄔᄕᄖᄗᄘᄙᄚᄛᄜᄝᄞᄟᄠᄡᄢᄣᄤᄥᄦᄧᄨᄩᄪᄫᄬᄭᄮᄯᄰᄱᄲᄳᄴᄵᄶᄷᄸᄹᄺᄻᄼᄽᄾᄿ
 1140 ᅀᅁᅂᅃᅄᅅᅆᅇᅈᅉᅊᅋᅌᅍᅎᅏᅐᅑᅒᅓᅔᅕᅖᅗᅘᅙᅚᅛᅜᅝᅞᅟᅠᅡᅢᅣᅤᅥᅦᅧᅨᅩ
 1180 ᆀᆁᆂᆃᆄᆅᆆᆇᆈᆉ
 11c0 ᇀᇁᇂᇃᇄᇅᇆᇇᇈᇉ
$ ./utf-8 --startcp 0x3130 --endcp 0x318f
startcp=3130(0x3130)
endcp=318f(0x318f)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
㄰ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿ
 3140 ㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿ
 3180 ㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ
$ ./utf-8 --startcp 0xa960 --endcp 0xa97f
startcp=a960(0xa960)
endcp=a97f(0xa97f)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
ꥠꥡꥢꥣꥤꥥꥦꥧꥨꥩꥪꥫꥬꥭꥮꥯꥰꥱꥲꥳꥴꥵꥶꥷꥸꥹꥺꥻꥼ꥽꥾
$ ./utf-8 --startcp 0xd7b0 --endcp 0xd7ff
startcp=d7b0(0xd7b0)
endcp=d7ff(0xd7ff)
      ----------------111111111111111122222222222222223333333333333333
      0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
      ================================================================
ힰힱힲힳힴힵힶힷힸힹힺힻힼힽힾힿ
 d7c0 ퟀퟁퟂퟃퟄퟅퟆ퟇퟈퟉퟊ퟋퟌퟍퟎퟏퟐퟑퟒퟓퟔퟕퟖퟗퟘퟙퟚퟛퟜퟝퟞퟟퟠퟡퟢퟣퟤퟥퟦퟧퟨퟩퟪퟫퟬퟭퟮퟯퟰퟱퟲퟳퟴퟵퟶퟷퟸퟹퟺퟻ퟼퟽퟾
$ newressu
00000 10955298622891139823978767469624270540320096250741050939155614833
00001 15916015913277331722288937064771768189593252684835170356246721839
00002 04039886350269819407135540091804515858430144820156936494057205603
00003 18471675307909851264083215017712660955498036699392294272957557298
00004 06629485130407066753882336886060902236769148397379408587433572338
00005 16968002406020534187490573765931119767553380391702394192871126932
00006 47486009968836713625873692500144966286246131846408332996524644757
00007 69338314951327162482945049158337976439471586020240534838578299151
00008 03912437379993151193634064497583817477809648893543558696267418176
00009 78142005792926824171979859871962451083815458844846170277633350868
$ newressu --ressu2
00000 37285017510609779869514940575475960020361480252238348227134059461
00001 12355232258882613760414797306554386597921126243112752334776680463
00002 02212118805502737321492467469657589057174849292270087270763283100
00003 29849511622306813093573265760907401757348104541563727310760589113
00004 15732018999953753080362222484264754467047657752953736770071877466
00005 51131335497163185790740553290169721590428044535088887662173176262
00006 11465438565611283088861668876938277182421391053985899811340713471
00007 72574285385631733457443358245283218440509028894018469417039942907
00008 75155718271160332421602701525554116085357479264288152761928514391
00009 69687786046783408891868012618107234151009548573863827848828920546
$ ressu2
00000 6e 2d 6e cf 89 6b c4 c4 c7 46 b8 55 d2 e6 23 3e f1 d4 cd d8 fd 3a 4b 23 e1 b1 6e 46 4f 4f c0 4e
00001 99 d5 0b 24 b9 0e 19 ec 2e 4c a4 f4 52 3b 54 08 89 6c d6 18 04 08 01 56 8d 37 2d ec 36 73 48 44
00002 b9 13 0d 4e 0f 22 43 b0 21 30 7a c2 2d c2 f3 76 48 be 7b a7 df 26 42 5a c1 d0 af 9b 6f a6 cd 59
00003 30 69 15 05 84 e4 52 2b 9a 09 04 07 ea d5 d3 76 d3 3f bd 03 f6 3a b3 10 60 99 38 b5 79 63 69 53
00004 d1 2e 08 63 ce f0 d1 1c b7 40 f0 c8 81 04 81 35 3d f0 5c 93 c4 67 7a 2b 52 98 ee d1 8a e8 25 7d
00005 75 cc 57 9f bc 31 9f fa e5 34 35 cc 56 00 27 f2 0b fb fc f4 bb fe 86 e7 3c 32 12 30 bc a8 d2 ff
00006 d8 4a a1 b6 5e 00 a5 6b 61 e5 d0 9d 3c 34 8d 56 d9 2a 66 25 4f 03 b3 79 5f 66 66 f3 5e 0d 1d 3b
00007 fc 2d 4d 7b ee ed 23 7d e6 56 4b 72 25 cc 16 4c 27 af 30 da e0 da 55 16 ae 05 56 4d f7 95 33 d2
00008 79 8c af be 74 21 1b 9c 15 e8 40 6d ae ae 70 0b cc 4a da a5 88 e6 f5 6a 6f ef 4c ae 57 ad 71 87
00009 e4 3a 85 32 a9 99 08 b5 4e c2 4d c2 d3 d2 9a 4c 2a 74 7a 50 49 4e d2 00 95 2b 73 ca 4d 91 69 c0
$ newressu --help
this help page                                    newressu --help/-?       
print random decimal digits (default)             newressu -d/--dec        
octal digits                                      newressu -o/--oct        
hexadecimal digits                                newressu -x/--hex        
binary digits                                     newressu -b/--bin        
decimal digits, with spaces between "words"       newressu -d --space      
binary digits, with spaces between "words"        newressu -b --space      
decimal digits, 30 lines                          newressu -d -l30         
decimal digits, 30 lines, no linenumbers          newressu -d -l30 --lineno
base 2 digits = decimal (0-1)                      newressu --base2         
base 8 digits = octal (0-7)                        newressu --base8         
base 10 digits = decimal (0-9)                     newressu --base10        
base 16 digits = hexadecimal (0-F)                 newressu --base16        
base 62 digits (0-9, A-Z, a-z)                    newressu --base62        
numbers in rand style listing                     newressu --rand          
numbers in 2 number groups                        newressu --space 2       
print numbers in 5 line groups                    newressu --newline 5     
fill all screen lines                             newressu -l*             
fill all screen columns                           newressu -c*             
fill screen columns and lines                     newressu --screen        
print decimal digits, 128 characters per line     newressu -d -c128        
print decimal numbers between 0-9                 newressu -d --lim10      
print hexadecimal numbers with decimal limit      newressu -d --lim10 -x   
print five letter uppercase words                 newressu --isupper --limBAAAAA
print decimal numbers with spaces and wordsize 10 newressu -d -s10 --space 
print rollings of dice (1-6)                      newressu -d --space --zero --lim7
print throws of coin (0,1)                        newressu -b -s1 --space  
print lotto numbers for finnish lotto 7x(1-40)    newressu -d --lim41 -w7 --zero --lotto
print 16 sorted decimal numbers from 0 to 99999   newressu -d -s5 --sort -w16
alphanumeric characters                           newressu --alnum         
alphabetic characters                             newressu --alpha         
printables excluding space                        newressu --graph         
lowercase characters                              newressu --lower         
punctuation characters                            newressu --punct         
uppercase characters                              newressu --upper         
material for passwords                            newressu -1              
danish/norwegian alphabet                         newressu --dnk/--nor     
finnish/norwegian alphabet                        newressu --fin/--swe     
russian alphabet                                  newressu --rus           
estonian alphabet                                 newressu --est           
lithuanian alphabet                               newressu --ltu           
latvian alphabet                                  newressu --lva           
french/gb/us/italian alphabet                     newressu --fra/--gbr/--usa/--ita
deutsch alphabet                                  newressu --deu           
greek alphabet                                    newressu --grc           
japan alphabet (hiragana, katakana, kanji)        newressu --jp            
japan alphabet (hiragana)                         newressu --jp1/--hir     
japan alphabet (katakana)                         newressu --jp2/--kat     
japan alphabet (kanji)                            newressu --jp3/--kan     
chinese alphabet                                  newressu --cn            
hebrew alphabet                                   newressu --heb           
hindi alphabet                                    newressu --hin/--ind     
korean alphabet                                   newressu --kor           
gothic alphabet                                   newressu --got           
"one time pad" (otp) with 5 numeric characters    newressu --otp5n/--otp1  
otp with 5 uppercase letters                      newressu --otp5a/--otp2  
otp with 4 uppercase letters                      newressu --otp4a/--otp3  
playing cards                                     newressu --cards         
playing card suits                                newressu --cardsuits     
chess men                                         newressu --chessmen      
print dice                                        newressu --dice          
print mahjong pieces                              newressu --mahjong       
print pattern1                                    newressu -i▌▙▄ / --pattern1
print pattern2                                    newressu -i◜◝◞◟ / --pattern2
print pattern2                                    newressu -i\\/ / --pattern3
print pattern2                                    newressu -i▧▨ / --pattern5
use randomness from ressu (default)               newressu --ressu         
use randomness from pseudo random ressu           newressu --pseudoressu   
use randomness from fast ressu                    newressu --fast/--fastressu
use randomness from single round of ressu         newressu --single/--singleressu
use randomness from fort                          newressu --fort          
use randomness from intel rdrand                  newressu --rdrand        
use randomness from intel rdseed                  newressu --rdseed        
use randomness from /dev/urandom                  newressu --urandom       
use randomness from /dev/random                   newressu --random        
area:FINLAND, Finland(fi), Åland(ax), count:2
area:DENMARK, Denmark(dk), FaroeIslands(fo), Greenland(gl), Greenland(gl), count:4
area:NORDIC, Finland(fi), Åland(ax), Sweden(se), Norway(no), Denmark(dk), FaroeIslands(fo), Iceland(is), Greenland(gl), count:8
area:BALTIC, Estonia(ee), Latvia(lv), Lithuania(lt), count:3
area:FRANCE, ClippertonIsland(fr), Guadeloupe(gp), Martinique(mq), FrenchGuiana(gf), Mayotte(yt), Réunion(re), NewCaledonia(nc), FrenchPolynesia(pf), WallisandFutuna(wf), Jersey(je), count:10
area: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
area:SPAIN, WesternSahara(eh), count:1
area: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
area:NORTHERNEUROPE, Finland(fi), Sweden(se), Norway(no), Denmark(dk), Iceland(is), Estonia(ee), Latvia(lv), Lithuania(lt), count:8
area: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
area:SOUTHERNEUROPE, Cyprus(cy), Greece(gr), Italy(it), Vatican(va), Malta(mt), Portugal(pt), SanMarino(sm), Spain(es), Turkey(tr), count:9
area: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
area: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
area: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
area:NORTHASIA, Russia(ru), count:1
area:EASTASIA, Bahrain(bh), China(cn), HongKong(hk), Japan(jp), SouthKorea(kr), Mongolia(mn), Macao(mo), NorthKorea(kp), Taiwan(tw), count:9
area:CENTRALASIA, Kazakhstan(kz), Kyrgyzstan(kg), Tajikistan(tj), Turkmenistan(tm), Uzbekistan(uz), count:5
area:SOUTHASIA, Afghanistan(af), Bangladesh(bd), Bhutan(bt), India(in), SriLanka(lk), Maldives(mv), Nepal(np), Pakistan(pk), count:8
area: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
area: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
area:NORTHAFRICA, Algeria(dz), Egypt(eg), Libya(ly), Madeira(ly), Morocco(ma), Tunisia(tn), WesternSahara(eh), count:7
area: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éunion(re), Rwanda(rw), Burundi(bi), Eritrea(er), Mauritius(mu), Mozambique(mz), Djibouti(dj), Seychelles(sc), count:21
area:CENTRALAFRICA, Congo(cg), DemocraticCongo(cd), Angola(ao), Cameroon(cm), Chad(td), Congo(cd), CentralAfrican(cf), Gabon(ga), EquatorialGuinea(gq), SãoToméandPríncipe(st), count:10
area:SOUTHAFRICA, SouthAfrica(za), Botswana(bw), Namibia(na), Lesotho(ls), Eswatini(sz), count:5
area: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
area: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éunion(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
area: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çao(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élemy(bl), SaintKitts(kn), SaintLucia(lc), SaintMartin(mf), SintMaarten(sx), TrinidadandTobago(tt), TurksandCaicos(tc), SaintPierre(pm), SaintVincent(vc), UnitedStatesofAmerica(us), VirginIslands(vi), count:44
area: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
area:USA, UnitedStatesofAmerica(us), VirginIslands(vi), Guam(gu), Americansamoa(as), count:4
area: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
area:AUSTRALASIA, Australia(au), NorFolkIsland(nf), NewZealand(nz), count:3
area:MELANESIA, Fiji(fj), PapuanewGuinea(pg), Vanuatu(vu), SolomonIslands(sb), count:4
area:MICRONESIA, Kiribati(ki), Nauru(nr), Micronesia(fm), Guam(gu), MarshallIslands(mh), NorthernMariana(mp), Palau(pw), count:7
area:POLYNESIA, FrenchPolynesia(pf), Samoa(ws), Americansamoa(as), Pitcairn(pn), NorFolkIsland(nf), Cookisland(ck), Niue(nu), Tokelau(tk), Tonga(to), count:9
area:BRICS, Russia(ru), Brazil(br), China(cn), India(in), SouthAfrica(za), count:5
area:ALL, Finland(fi), Åland(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çao(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élemy(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éunion(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ãoToméandPríncipe(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
************************************************************************
00000 63711265569033709750929554591985173713238988280649712433820070348

Tässä ressu2:n sorsa:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>

#include <sys/time.h>
#include <time.h>

#define MAIN 2

unsigned char *procname;
static unsigned char *programname = "Ressu2 version 1.00 ©";
static unsigned char *copyright = "Copyright (c) 2013-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";
int my_output = 0;

void my_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
  int c;

  if(my_output) {
    fprintf(stdout,"\n");
    my_output = 0;
  }
  for(c = 0; c < len; c++) {
    if(c % linelen == 0) {
      if(c > 0)
	fprintf(stdout,"\n");
      fprintf(stdout,"%-10s", header);
    }
    fprintf(stdout," %02x", buf[c]);
  }
  fprintf(stdout,"\n");
  fflush(stdout);
}

#define aDEBUG8 2

#define aUSE_URANDOM 2
#define USE_RESSU2 2
#define USE_PSEUDORESSU2 2
#define USE_RESSU2TWIST 2

#if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

static unsigned long long my_ressu_useconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}

static unsigned char my_ressu_lowusec() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

static int randomness = 0;

#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )

static void my_ressu2_round(int size, unsigned char *buffer) // ressu JariK 2013, 2025
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = my_ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	randomness++;
      }
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + 16 + buffer[d] + 2) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = my_ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

#include "newressu.h"

#define RESSU2_BYTES 2048 // now 2048
#define RESSU2_RANDOMNESS_NEEDED 2048 // now 2048 
#define RESSU2_CLOCKS_NEEDED 20480 // now 20480
#define RESSU2_MINIMUM_ROUNDS 5 // now 5

void my_ressu2_bytes(int size, unsigned char *buffer) // Ressu2 v1.1 JariK 2013, 2025, 2026
{
  int c, d, clocksused;
  static int ressu_pos = 0, initneeded = 1;
  static unsigned char ressu[RESSU2_BYTES];
  
  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      if(initneeded) {
	memset(&ressu, 0, sizeof(ressu));
	initneeded = 0;
      }
      randomness = 0;
      clocksused = 0;
      //memset(&ressu, 0, sizeof(ressu));
      
      for(d = 0; d < RESSU2_MINIMUM_ROUNDS ||
	    randomness < RESSU2_RANDOMNESS_NEEDED ||
	    clocksused < RESSU2_CLOCKS_NEEDED
	    ; d++) {
	my_ressu2_round(sizeof(ressu), ressu);
	clocksused += (sizeof(ressu) * 8);
      }
      
#ifdef DEBUG8
      my_dump("myressu2g", sizeof(ressu), ressu, 32);      
#endif
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  my_dump("myressu2", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

#if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

unsigned char cvar[16];
int cvarsize = 0;

void inccvar()
{
  int c;

  /* 16 bytes, LSB first */
  for(c = 0; ++cvar[c] == 0 && c < sizeof(cvar) - 1; c++);

  if(cvarsize < c)
    cvarsize = c;

#ifdef DEBUG20
  ressu_dump("cvar", cvarsize + 1, cvar, 32);
#endif
}

void clearcvar()
{
  int c;

  cvarsize = 0;
  
  for(c = 0; c < sizeof(cvar); c++)
    cvar[c] = 0;

  for(c = 0; c < sizeof(cvar); c++)
    if(cvar[c] != 0)
      cvarsize = c;
}

#include "sha256.h"

#define PSEUDORESSU2_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define PSEUDORESSU2_TOPUP_TWICE 2 // off by default

static unsigned char pseudoressu2_key[HashLen]; // 32 bytes, 256 bits

static void my_pseudoressu2_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu2_addrandomness(int size, unsigned char *buffer)
{
  unsigned long long usec;
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  usec = my_ressu_useconds(); // add timestamp to hash
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  usec = clock(); // add processor time to hash (for randomness)
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  HashUpdate(&hash, buffer, size); // add given randomness to hash
  HashFinal(pseudoressu2_key, &hash); // save as new key
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu2_topup()
{
  unsigned char topup[PSEUDORESSU2_TOPUP_SIZE]; // 32 bytes, 256 bits

  memset(&topup, 0, sizeof(topup)); // forget topup
  my_ressu2_bytes(sizeof(topup), topup);
#ifdef DEBUG8
  my_dump("topup", sizeof(topup), topup, 32);
#endif
  my_pseudoressu2_addrandomness(sizeof(topup), topup);

  memset(&topup, 0, sizeof(topup)); // forget topup
}

void my_pseudoressu2_bytes(int size, unsigned char *buffer) // JariK 2022, 2025
{
  int c;
  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
  static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudoressu_pos == 0) {
      if(topup_counter == 0) {
	if(initneeded) {
	  my_ressu2_bytes(sizeof(pseudoressu2_key), pseudoressu2_key); // get first key
#ifdef DEBUG8
	  my_dump("first key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
	  initneeded = 0;
	} // end of if(initneeded
	
	my_pseudoressu2_topup(); // add randomness to key, first block also
#ifdef PSEUDORESSU2_TOPUP_TWICE
	my_pseudoressu2_topup(); // add randomness to key, first block also
#endif
	topup_counter = PSEUDORESSU2_TOPUP_BYTES;
      } // end of if(topup_counter == 0
      
      my_pseudoressu2_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
      my_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
      topup_counter -= sizeof(pseudoressu);
    } // end of if(pseudoressu_pos == 0

    buffer[c] ^= pseudoressu[pseudoressu_pos];
    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
  } // end of for(c = 0; c < size; c++
  
  my_pseudoressu2_internalbytes(pseudoressu2_key); // replace key with new random one
#ifdef DEBUG8
  my_dump("new key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
#ifdef DEBUG8
  my_dump("pseudoressu", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

#ifdef USE_RESSU2TWIST

void my_ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023, 2025
{
  //urandom_bytes(size, buffer);
  my_ressu2_bytes(size, buffer);
  my_pseudoressu2_bytes(size, buffer);
#ifdef DEBUG8
  my_dump("ressu2twist", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_RESSU2TWIST

#ifdef USE_URANDOM

void my_readfile_xor(int size, unsigned char *buffer, unsigned char *filename)
{
  int c, n, filebuffer_pos = 0;
  unsigned char filebuffer[64];
  FILE *fp1;

  if((fp1 = fopen(filename, "rb")) == NULL) {
    fprintf(stderr,"%s: fopen(): cannot open file %s\n",
	    procname, filename);
    exit(1);
  }

  for(c = 0; c < size; c++) {
    if(filebuffer_pos == 0) {
      n = (size - c < sizeof(filebuffer)) ? size - c : sizeof(filebuffer);
      if(fread(filebuffer, 1, n, fp1) < n) {
	fprintf(stderr,"%s: fread(): cannot read file %s\n",
		procname, filename);
	exit(1);
      }
#ifdef DEBUG8
      my_dump("file", n, filebuffer, 32);
#endif
    } // end of if(file_pos == 0
    buffer[c] ^= filebuffer[filebuffer_pos];
    filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);
  } // end of for(c = 0; c < size; c++

  fclose(fp1);

  memset(filebuffer, 0, sizeof(filebuffer)); // forget file
}

static unsigned char urandomfilename[128] = "/dev/urandom";

void my_urandom_bytes(int size, unsigned char *buffer)
{
  my_readfile_xor(size, buffer, urandomfilename);
#ifdef DEBUG8
  my_dump("urandom", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_URANDOM

void my_random_bytes(int size, unsigned char *buffer)
{
#ifdef USE_URANDOM
  my_urandom_bytes(size, buffer);
#endif
  //ressu_round(size, buffer);
  //ressu_genbytes(size, buffer);
  //pseudoressu_bytes(size, buffer);
  //ressutwist_bytes(size, buffer);
  //my_ressu2_round(size, buffer);
#ifdef USE_PSEUDORESSU2
  my_pseudoressu2_bytes(size, buffer);
#endif
#ifdef USE_RESSU2TWIST
  my_ressu2twist_bytes(size, buffer);
#endif
#ifdef USE_RESSU2
  my_ressu2_bytes(size, buffer);
#endif
}

#define GENT_SIZE 128

static unsigned char gent[GENT_SIZE];
static unsigned int gent_pos = 0;

int my_random_byte()
{
  unsigned char ch;
  static int initneeded = 1;

  if(gent_pos == 0) {
    if(initneeded) {
      memset(&gent, 0, sizeof(gent));
      initneeded = 0;
    }
    my_random_bytes(sizeof(gent), gent);
  }
  ch = gent[gent_pos];
  gent_pos = (gent_pos + 1) % sizeof(gent);

  return(ch);
}

unsigned long my_random_genlimit(unsigned long limit)
{
  int c;
  unsigned long word;
  static unsigned long lastlimit = 0, highlimit;
  static int bytes;
  
  if(lastlimit != limit) { // if limit changes, calculate new highlimit and bytes
    lastlimit = limit;
    if(limit <= 0x100) {
      // highest multiplier of limit that fits to needed bytes
      highlimit = (0x100 / limit) * limit;
      // number of bytes needed
      bytes = 1;
    } else if(limit <= 0x10000) {
      highlimit = (0x10000 / limit) * limit;
      bytes = 2;
    } else if(limit <= 0x1000000) {
      highlimit = (0x1000000 / limit) * limit;
      bytes = 3;
    } else if(limit <= 0x100000000) {
      highlimit = (0x100000000 / limit) * limit;
      bytes = 4;
    } else if(limit <= 0x10000000000) {
      highlimit = (0x10000000000 / limit) * limit;
      bytes = 5;
    } else if(limit <= 0x1000000000000) {
      highlimit = (0x1000000000000 / limit) * limit;
      bytes = 6;
    } else if(limit <= 0x100000000000000) {
      highlimit = (0x100000000000000 / limit) * limit;
      bytes = 7;
    } else { // if(limit <= 0xffffffffffffffff) {
      highlimit = (0xffffffffffffffff / limit) * limit;      
      bytes = 8;
    }
  } // if(lastlimit != limit)

  for(;;) {
    word = 0;
    for(c = 0; c < bytes; c++)
      word = word << 8 | my_random_byte();
    if(word < highlimit)
      break;
  }

  word %= limit;
  
  return(word);
}

void ressu2_version()
{
  fprintf(stderr, "%s", programname); // touch these outside #ifdef MAIN
  fprintf(stderr, ", %s", copyright);
}

#include <sys/ioctl.h> // for TIOCGWINSZ

#ifdef MAIN

int main(int argc, char *argv[])
{
  int c, d;

  procname = argv[0];

  //
  // look thru command line parameters
  //

  for(c = 1; c < argc; c++) {
    if(!strcmp("--copyright", argv[c]) ||
       !strcmp("--version", argv[c])) {
      ressu2_version();
#ifdef SHA256
      fprintf(stderr,"\nsha256(");
      for(int c = 0; c < HashLen; c++) {
	fprintf(stderr, "%02x", programfiledigest[c]);
      }
#endif // end of #ifdef SHA256

    }
  }

  for(c = 0; c < 10; c++) {
    fprintf(stdout, "%05x", c);
    my_output = 1;
    for(d = 0; d < 32; d++) {
      fprintf(stdout, " ");
      fprintf(stdout, "%02llx", (unsigned long long) my_random_genlimit(0x100));
    }
    fprintf(stdout,"\n");
  }
}
#endif // end of #ifdef MAIN

Tässä lisättyjä lippuja:

grep FRANCE newressu.c
NORTHAMERICA" },
  { "🇬🇫", "🇬🇫: gf, guf, FrenchGuiana, SOUTHAMERICA, FRANCE" }, // French Guiana
  { "🇾🇹", "🇾🇹: yt, myt, Mayotte, FRANCE, AFRICA, EASTAFRICA" },
  { "🇷🇪", "🇷🇪: re, reu, Réunion, reunion, FRANCE, AFRICA, EASTAFRICA" }, // Réunion
  { "🇳🇨", "🇳🇨: nc, ncl, NewCaledonia, FRANCE, OCEANIA" }, // New Caledonia
  { "🇵🇫", "🇵🇫: pf, pyf, FrenchPolynesia, FRANCE, POLYNESIA, OCEANIA" }, // French Polynesia
  { "🇼🇫", "🇼🇫: wf, wlf, WallisandFutuna, FRANCE, OCEANIA" }, // Wallis and Futuna
  { "🇯🇪", "🇯🇪: je, jey, Jersey, FRANCE" },
grep EU newressu.c
EUROPE, EURASIA, NORDIC" },
  { "🇳🇴", "🇳🇴: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇮🇸", "🇮🇸: is, isl, Iceland, NORTHERNEUROPE, EUROPE,

, edellinen pulpauttaa mukaan myös seuraavat rivit:

    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;
#define PSEUDORESSU_LIMIT 1048576 // limit between rekeys
    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;

, grep EU, koko materiaalistani tuo seuraavat rivit: (ylimääräiset koodirivit poistettuna; ja tässäkin kaikki ylimääräiset ja puuttuvat ovat minun virheitäni)

  { "🇫🇮", "🇫🇮: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND" },
  { "🇸🇪", "🇸🇪: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇪🇪", "🇪🇪: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇻", "🇱🇻: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇹", "🇱🇹: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇦🇹", "🇦🇹: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇪", "🇧🇪: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇬", "🇧🇬: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇷", "🇭🇷: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇾", "🇨🇾: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇨🇿", "🇨🇿: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA" },  // Czech Republic Czechia
  { "🇫🇷", "🇫🇷: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇩🇪", "🇩🇪: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇷", "🇬🇷: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇺", "🇭🇺: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇹", "🇮🇹: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇱🇺", "🇱🇺: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇹", "🇲🇹: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇳🇱", "🇳🇱: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇵🇱", "🇵🇱: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇵🇹", "🇵🇹: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇴", "🇷🇴: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇰", "🇸🇰: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇮", "🇸🇮: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇪🇸", "🇪🇸: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇭", "🇨🇭: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA" },
    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;

grep NORTHERNEUROPE

  { "🇫🇮", "🇫🇮: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND" },
  { "🇸🇪", "🇸🇪: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇳🇴", "🇳🇴: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇮🇸", "🇮🇸: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇪🇪", "🇪🇪: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇻", "🇱🇻: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇹", "🇱🇹: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
    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;

grep EASTERNEUROPE:

  { "🇺🇦", "🇺🇦: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇱", "🇦🇱: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇲", "🇦🇲: am, arm, Armenia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇦🇿", "🇦🇿: az, aze, Azerbaijan, EASTERNEUROPE, EUROPE, WESTASIA, ASIA, EURASIA" },
  { "🇧🇾", "🇧🇾: by, blr, Belarus, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇦", "🇧🇦: ba, bih, BosniaandHerzegovina, EASTERNEUROPE, EUROPE" }, // Bosnia and Herzegovina
  { "🇧🇬", "🇧🇬: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇷", "🇭🇷: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇿", "🇨🇿: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA" },  // Czech Republic Czechia
  { "🇬🇪", "🇬🇪: ge, geo, Georgia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇭🇺", "🇭🇺: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇩", "🇲🇩: md, mda, Moldova, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇪", "🇲🇪: me, mne, Montenegro, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇰", "🇲🇰: mk, mkd, Northmacedonia, EASTERNEUROPE, EUROPE, EURASIA" }, // North Macedonia
  { "🇵🇱", "🇵🇱: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇴", "🇷🇴: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇺", "🇷🇺: ru, rus, Russia, EASTERNEUROPE, EUROPE, EURASIA, NORTHASIA, ASIA, BRICS" },
  { "🇷🇸", "🇷🇸: rs, srb, Serbia, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇰", "🇸🇰: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇮", "🇸🇮: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
    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;

grep SOUTHERNEUROPE:

  { "🇨🇾", "🇨🇾: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇬🇷", "🇬🇷: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇹", "🇮🇹: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇻🇦", "🇻🇦: va, vat, Vatican, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇹", "🇲🇹: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇵🇹", "🇵🇹: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇲", "🇸🇲: sm, smr, SanMarino, SOUTHERNEUROPE, EUROPE, EURASIA" }, // San Marino
  { "🇪🇸", "🇪🇸: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇹🇷", "🇹🇷: tr, tur, Turkey, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
    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;

grep WESTERNEUROPE

  { "🇦🇩", "🇦🇩: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇹", "🇦🇹: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇪", "🇧🇪: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇫🇷", "🇫🇷: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇩🇪", "🇩🇪: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇱🇮", "🇱🇮: li, lie, Liechtenstein, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇱🇺", "🇱🇺: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇨", "🇲🇨: mc, mco, Monaco, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇳🇱", "🇳🇱: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇭", "🇨🇭: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇧", "🇬🇧: gb, gbr, UnitedKingdom, UK, WESTERNEUROPE, EUROPE, EURASIA" },
    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;

grep ALL tuo seuraavat rivit: (näissä voi muuten olla virheitä, aika kauan yritin aikanaan tehdä ja tarkistaa niitä…)

Tässä kaikki arkistoni liput:

  { "🇫🇮", "🇫🇮: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND" },
  { "🇦🇽", "🇦🇽: ax, ala, Åland, aland, NORDIC, FINLAND" },
  { "🇸🇪", "🇸🇪: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇳🇴", "🇳🇴: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇫🇴", "🇫🇴: fo, fro, FaroeIslands, NORDIC, DENMARK" },
  { "🇮🇸", "🇮🇸: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇬🇱", "🇬🇱: gl, grl, Greenland, NORTHAMERICA, NORDIC, DENMARK" },
  { "🇪🇪", "🇪🇪: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇻", "🇱🇻: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇹", "🇱🇹: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇺🇦", "🇺🇦: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇱", "🇦🇱: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇩", "🇦🇩: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇲", "🇦🇲: am, arm, Armenia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇦🇹", "🇦🇹: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇿", "🇦🇿: az, aze, Azerbaijan, EASTERNEUROPE, EUROPE, WESTASIA, ASIA, EURASIA" },
  { "🇧🇾", "🇧🇾: by, blr, Belarus, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇪", "🇧🇪: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇦", "🇧🇦: ba, bih, BosniaandHerzegovina, EASTERNEUROPE, EUROPE" }, // Bosnia and Herzegovina
  { "🇧🇬", "🇧🇬: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇷", "🇭🇷: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇾", "🇨🇾: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇨🇿", "🇨🇿: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA" },  // Czech Republic Czechia
  { "🇫🇷", "🇫🇷: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇪", "🇬🇪: ge, geo, Georgia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇩🇪", "🇩🇪: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇷", "🇬🇷: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇺", "🇭🇺: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇹", "🇮🇹: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇻🇦", "🇻🇦: va, vat, Vatican, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇰🇿", "🇰🇿: kz, kaz, Kazakhstan, EUROPE, EURASIA, CENTRALASIA, ASIA" },
  { "🇱🇮", "🇱🇮: li, lie, Liechtenstein, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇱🇺", "🇱🇺: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇹", "🇲🇹: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇩", "🇲🇩: md, mda, Moldova, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇪", "🇲🇪: me, mne, Montenegro, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇨", "🇲🇨: mc, mco, Monaco, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇪", "🇲🇪: me, mne, Montenegro, EUROPE, EURASIA" },
  { "🇳🇱", "🇳🇱: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇰", "🇲🇰: mk, mkd, Northmacedonia, EASTERNEUROPE, EUROPE, EURASIA" }, // North Macedonia
  { "🇵🇱", "🇵🇱: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇵🇹", "🇵🇹: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇴", "🇷🇴: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇺", "🇷🇺: ru, rus, Russia, EASTERNEUROPE, EUROPE, EURASIA, NORTHASIA, ASIA, BRICS" },
  { "🇸🇲", "🇸🇲: sm, smr, SanMarino, SOUTHERNEUROPE, EUROPE, EURASIA" }, // San Marino
  { "🇷🇸", "🇷🇸: rs, srb, Serbia, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇰", "🇸🇰: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇮", "🇸🇮: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇪🇸", "🇪🇸: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇭", "🇨🇭: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇹🇷", "🇹🇷: tr, tur, Turkey, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇬🇧", "🇬🇧: gb, gbr, UnitedKingdom, UK, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: gb, gbr, England, UK" },
  { "🇮🇪", "🇮🇪: gb, gbr, Scotland, UK" },
  { "🇮🇪", "🇮🇪: gb, gbr, Wales, UK" },
  { "🇬🇮", "🇬🇮: gi, gib, Gibraltar, UK" },
  { "🇸🇯", "🇸🇯: sj, sjm, JanMayen, NORWAY" }, // Jan Mayen
  { "🇦🇮", "🇦🇮: ai, aia, Anguilla, NORTHAMERICA, UK" },
  { "🇦🇬", "🇦🇬: ag, atg, AntiguaAndBarbuda, NORTHAMERICA" }, // Antigua and Barbuda 
  { "🇦🇼", "🇦🇼: aw, sbw, Aruba, NORTHAMERICA" }, 
  { "🇧🇸", "🇧🇸: bs, bhs, Bahamas, NORTHAMERICA" },
  { "🇧🇧", "🇧🇧: bb, brb, Barbados, NORTHAMERICA" },
  { "🇧🇿", "🇧🇿: bz, blz, Belize, NORTHAMERICA" },
  { "🇧🇲", "🇧🇲: bm, bmu, Bermuda, UK, NORTHAMERICA" },
  { "🇧🇶", "🇧🇶: bq, bes, Bonaire, NETHERLANDS, NORTHAMERICA" },
  { "🇻🇬", "🇻🇬: vg, vgb, BritishVirginIslands, UK, NORTHAMERICA" }, // British Virgin Islands
  { "🇨🇦", "🇨🇦: ca, can, Canada, NORTHAMERICA" },
  { "🇰🇾", "🇰🇾: ky, cym, CaymanIslands, UK, NORTHAMERICA" },
  { "🇫🇷", "🇫🇷: fr, fra, ClippertonIsland, FRANCE, NORTHAMERICA" },
  { "🇨🇷", "🇨🇷: cr, cri, CostaRica, NORTHAMERICA" },
  { "🇨🇺", "🇨🇺: cu, cub, Cuba, NORTHAMERICA" },
  { "🇨🇼", "🇨🇼: cw, cuw, Curaçao, curacao, NORTHAMERICA" },
  { "🇩🇲", "🇩🇲: dm, dma, Dominica, NORTHAMERICA" },
  { "🇩🇴", "🇩🇴: do, dom, DominicanRepublic, NORTHAMERICA" }, // Dominican Republic
  { "🇸🇻", "🇸🇻: sv, slv, ElSalvador, NORTHAMERICA" },
  { "🇬🇱", "🇬🇱: gl, grl, Greenland, DENMARK, NORTHAMERICA" },
  { "🇬🇩", "🇬🇩: gd, grd, Grenada, NORTHAMERICA" },
  { "🇬🇵", "🇬🇵: gp, glp, Guadeloupe, FRANCE, NORTHAMERICA" },
  { "🇬🇹", "🇬🇹: gt, gtm, Guatemala, NORTHAMERICA" },
  { "🇭🇹", "🇭🇹: ht, hti, Haiti, NORTHAMERICA" },
  { "🇭🇳", "🇭🇳: hn, hnd, Honduras, NORTHAMERICA" },
  { "🇯🇲", "🇯🇲: jm, jam, Jamaica, NORTHAMERICA" },
  { "🇲🇶", "🇲🇶: mq, mtq, Martinique, FRANCE, NORTHAMERICA" },
  { "🇲🇽", "🇲🇽: mx, mex, Mexico, NORTHAMERICA" },
  { "🇲🇸", "🇲🇸: ms, msr, Montserrat, UK, NORTHAMERICA" },
  { "🇳🇮", "🇳🇮: ni, nic, Nicaragua, NORTHAMERICA" },
  { "🇵🇦", "🇵🇦: pa, pan, Panama, NORTHAMERICA" },
  { "🇵🇷", "🇵🇷: pr, pri, PuertoRico, NORTHAMERICA" },
  { "🇧🇶", "🇧🇶: bq, bes, Saba, NORTHAMERICA" },
  { "🇧🇱", "🇧🇱: bl, blm, SaintBarthélemy, saintbarthelemy, NORTHAMERICA" }, // Saint Barthélemy
  { "🇰🇳", "🇰🇳: kn, kna, SaintKitts, NORTHAMERICA" }, // Saint Kitts and Nevis
  { "🇱🇨", "🇱🇨: lc, lca, SaintLucia, NORTHAMERICA" }, // Saint Lucia
  { "🇲🇫", "🇲🇫: mf, maf, SaintMartin, NORTHAMERICA" }, // Collectivity of Saint Martin
  { "🇸🇽", "🇸🇽: sx, sxm, SintMaarten, NORTHAMERICA" }, // Sint Maarten
  { "🇹🇹", "🇹🇹: tt, tto, TrinidadandTobago, NORTHAMERICA" }, // Trinidad and Tobago
  { "🇹🇨", "🇹🇨: tc, tca, TurksandCaicos, UK, NORTHAMERICA" }, // Turks and Caicos Islands
  { "🇵🇲", "🇵🇲: pm, spm, SaintPierre, NORTHAMERICA" }, // Saint Pierre and Miquelon
  { "🇻🇨", "🇻🇨: vc, vct, SaintVincent, NORTHAMERICA" }, // Saint Vincent and the Grenadines
  { "🇺🇸", "🇺🇸: us, usa, UnitedStatesofAmerica, USA, NORTHAMERICA" }, // United States of America
  { "🇻🇮", "🇻🇮: vi, vir, VirginIslands, USA, NORTHAMERICA" }, // United States Virgin Islands
  { "🇧🇻", "🇧🇻: bv, bvt, BouvetIsland" }, // Bouvet Island
  { "🇺🇲", "🇺🇲: um, umi, Navassa" },
  { "🇸🇭", "🇸🇭: sh, shn, SaintHelena" }, // Saint Helena
  { "🇦🇷", "🇦🇷: ar, arg, Argentina, SOUTHAMERICA" },
  { "🇧🇴", "🇧🇴: bo, bol, Bolivia, SOUTHAMERICA" },
  { "🇧🇷", "🇧🇷: br, bra, Brazil, SOUTHAMERICA, BRICS" },
  { "🇨🇱", "🇨🇱: cl, chl, Chile, SOUTHAMERICA" },
  { "🇨🇴", "🇨🇴: co, col, Colombia, SOUTHAMERICA" },
  { "🇪🇨", "🇪🇨: ec, ecu, Ecuador, SOUTHAMERICA" },
  { "🇫🇰", "🇫🇰: fk, flk, FalklandIslands, UK, SOUTHAMERICA" }, // Falkland Islands
  { "🇬🇫", "🇬🇫: gf, guf, FrenchGuiana, SOUTHAMERICA, FRANCE" }, // French Guiana
  { "🇬🇾", "🇬🇾: gy, guy, Guyana, SOUTHAMERICA" },
  { "🇵🇾", "🇵🇾: py, pry, Paraguay, SOUTHAMERICA" },
  { "🇵🇪", "🇵🇪: pe, per, Peru, SOUTHAMERICA" },
  { "🇬🇸", "🇬🇸: gs, sgs, SouthGeorgia, SOUTHAMERICA" }, // South Georgia and the South Sandwich Islands
  { "🇸🇷", "🇸🇷: sr, sur, Suriname, SOUTHAMERICA" },
  { "🇺🇾", "🇺🇾: uy, ury, Uruguay, SOUTHAMERICA" },
  { "🇻🇪", "🇻🇪: ve, ven, Venezuela, SOUTHAMERICA" },
  { "🇦🇪", "🇦🇪: ae, are, UnitedArabEmirates, WESTASIA, ASIA, EURASIA" }, // United Arab Emirates
  { "🇦🇫", "🇦🇫: af, afg, Afghanistan, SOUTHASIA, ASIA, EURASIA" },
  { "🇧🇩", "🇧🇩: bd, bgd, Bangladesh, SOUTHASIA, ASIA, EURASIA" },
  { "🇧🇭", "🇧🇭: bh, bhr, Bahrain, EASTASIA, ASIA, EURASIA" },
  { "🇧🇳", "🇧🇳: bn, brn, Brunei, ASIA, EURASIA" },
  { "🇧🇹", "🇧🇹: bt, btn, Bhutan, SOUTHASIA, ASIA, EURASIA" },
  { "🇨🇳", "🇨🇳: cn, chn, China, EASTASIA, ASIA, EURASIA, BRICS" },
  { "🇭🇰", "🇭🇰: hk, hkg, HongKong, EASTASIA, ASIA, EURASIA" },
  { "🇮🇩", "🇮🇩: id, idn, Indonesia, ASIA, EURASIA" },
  { "🇮🇱", "🇮🇱: il, isr, Israel, WESTASIA, ASIA, EURASIA" },
  { "🇮🇳", "🇮🇳: in, ind, India, SOUTHASIA, ASIA, EURASIA, BRICS" },
  { "🇮🇶", "🇮🇶: iq, irq, Iraq, WESTASIA, ASIA, EURASIA" },
  { "🇮🇷", "🇮🇷: ir, irn, Iran, WESTASIA, ASIA, EURASIA" },
  { "🇯🇴", "🇯🇴: jo, jor, Jordan, WESTASIA, ASIA, EURASIA" },
  { "🇯🇵", "🇯🇵: jp, jpn, Japan, EASTASIA, ASIA, EURASIA" },
  { "🇰🇬", "🇰🇬: kg, kgz, Kyrgyzstan, CENTRALASIA, ASIA, EURASIA" },
  { "🇰🇭", "🇰🇭: kh, khm, Cambodia, ASIA, EURASIA" },
  { "🇰🇷", "🇰🇷: kr, kor, SouthKorea, EASTASIA, ASIA, EURASIA" },
  { "🇰🇼", "🇰🇼: kw, kwt, Kuwait, WESTASIA, ASIA, EURASIA" },
  { "🇱🇦", "🇱🇦: la, lao, Laos, ASIA, EURASIA" },
  { "🇱🇧", "🇱🇧: lb, lbn, Lebanon, WESTASIA, ASIA, EURASIA" },
  { "🇱🇰", "🇱🇰: lk, lka, SriLanka, SOUTHASIA, ASIA, EURASIA" },
  { "🇲🇳", "🇲🇳: mn, mng, Mongolia, EASTASIA, ASIA, EURASIA" },
  { "🇲🇴", "🇲🇴: mo, mac, Macao, EASTASIA, ASIA, EURASIA" },
  { "🇲🇻", "🇲🇻: mv, mdv, Maldives, SOUTHASIA, ASIA, EURASIA" },
  { "🇲🇲", "🇲🇲: mm, mmr, Myanmar, ASIA, EURASIA" },
  { "🇲🇾", "🇲🇾: my, mys, Malaysia, ASIA, EURASIA" },
  { "🇰🇵", "🇰🇵: kp, prk, NorthKorea, EASTASIA, ASIA, EURASIA" },
  { "🇳🇵", "🇳🇵: np, npl, Nepal, SOUTHASIA, ASIA, EURASIA" },
  { "🇴🇲", "🇴🇲: om, omn, Oman, WESTASIA, ASIA, EURASIA" },
  { "🇵🇭", "🇵🇭: ph, phl, Philippines, ASIA, EURASIA" },
  { "🇵🇰", "🇵🇰: pk, pak, Pakistan, SOUTHASIA, ASIA, EURASIA" },
  { "🇵🇸", "🇵🇸: ps, pse, Palestine, WESTASIA, ASIA, EURASIA" },
  { "🇶🇦", "🇶🇦: qa, qat, Qatar, WESTASIA, ASIA, EURASIA" },
  { "🇸🇦", "🇸🇦: sa, sau, SaudiArabia, WESTASIA, ASIA, EURASIA" },
  { "🇸🇬", "🇸🇬: sg, sgb, Singapore, ASIA, EURASIA" },
  { "🇸🇾", "🇸🇾: sy, syr, Syria, WESTASIA, ASIA, EURASIA" },
  { "🇹🇭", "🇹🇭: th, tha, Thailand, ASIA, EURASIA" },
  { "🇹🇯", "🇹🇯: tj, tjk, Tajikistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇹🇱", "🇹🇱: tl, tls, EastTimor, ASIA, EURASIA" },
  { "🇹🇲", "🇹🇲: tm, tkm, Turkmenistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇹🇼", "🇹🇼: tw, twn, Taiwan, EASTASIA, ASIA, EURASIA" },
  { "🇺🇿", "🇺🇿: uz, uzb, Uzbekistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇻🇳", "🇻🇳: vn, vnm, Vietnam, ASIA, EURASIA" },
  { "🇾🇪", "🇾🇪: ye, yem, Yemen, WESTASIA, ASIA, EURASIA" },
  { "🇳🇪", "🇳🇪: ne, ner, Nigeria, AFRICA, WESTAFRICA" },
  { "🇪🇹", "🇪🇹: et, eth, Ethiopia, AFRICA, AFRICA, EASTAFRICA" },
  { "🇪🇷", "🇪🇷: er, eri, Eritrea, AFRICA, EASTAFRICA" },
  { "🇨🇬", "🇨🇬: cg, cog, Congo, AFRICA, CENTRALAFRICA" }, // Rebublic of the Congo
  { "🇨🇩", "🇨🇩: cd, cod, DemocraticCongo, AFRICA, CENTRALAFRICA" }, // Democratic Rebublic of the Congo
  { "🇹🇿", "🇹🇿: tz, tza, Tanzania, AFRICA, EASTAFRICA" },
  { "🇿🇦", "🇿🇦: za, zaf, SouthAfrica, AFRICA, SOUTHAFRICA, BRICS" },
  { "🇰🇪", "🇰🇪: ke, ken, Kenya, AFRICA, EASTAFRICA" },
  { "🇺🇬", "🇺🇬: ug, uga, Uganda, AFRICA, EASTAFRICA" },
  { "🇸🇸", "🇸🇸: ss, ssd, SouthSudan, AFRICA, EASTAFRICA" },
  { "🇸🇩", "🇸🇩: sd, sdn, Sudan, AFRICA, EASTAFRICA" },
  { "🇩🇿", "🇩🇿: dz, dza, Algeria, AFRICA, NORTHAFRICA" },
  { "🇪🇬", "🇪🇬: eg, egy, Egypt, AFRICA, NORTHAFRICA, WESTASIA, ASIA, EURASIA" },
  { "🇱🇾", "🇱🇾: ly, lby, Libya, AFRICA, NORTHAFRICA" },
  { "🇱🇾", "🇱🇾: ly, lby, Madeira, AFRICA, NORTHAFRICA" },
  { "🇲🇦", "🇲🇦: ma, mar, Morocco, AFRICA, NORTHAFRICA" },
  { "🇦🇴", "🇦🇴: ao, ago, Angola, AFRICA, CENTRALAFRICA" },
  { "🇬🇭", "🇬🇭: gh, gha, Ghana, AFRICA, WESTAFRICA" },
  { "🇲🇿", "🇲🇿: mz, moz, Mozambique, AFRICA" },
  { "🇲🇬", "🇲🇬: mg, mdg, Madagascar, AFRICA, EASTAFRICA" },
  { "🇾🇹", "🇾🇹: yt, myt, Mayotte, FRANCE, AFRICA, EASTAFRICA" },
  { "🇨🇮", "🇨🇮: ci, civ, IvoryCoast, AFRICA, WESTAFRICA" },
  { "🇨🇲", "🇨🇲: cm, cmr, Cameroon, AFRICA, CENTRALAFRICA" },
  { "🇳🇪", "🇳🇪: ne, ner, Niger, AFRICA, WESTAFRICA" },
  { "🇧🇫", "🇧🇫: bf, bfa, BurkinaFaso, AFRICA, WESTAFRICA" }, // Burkina Faso
  { "🇲🇱", "🇲🇱: ml, mli, Mali, AFRICA, WESTAFRICA" },
  { "🇲🇼", "🇲🇼: mw, mwi, Malawi, AFRICA, EASTAFRICA" },
  { "🇿🇲", "🇿🇲: zm, zmb, Zambia, AFRICA, EASTAFRICA" },
  { "🇹🇩", "🇹🇩: td, tcd, Chad, AFRICA, CENTRALAFRICA" },
  { "🇸🇴", "🇸🇴: so, som, Somalia, AFRICA, EASTAFRICA" },
  { "🇸🇳", "🇸🇳: sn, sen, Senegal, AFRICA, WESTAFRICA" },
  { "🇿🇼", "🇿🇼: zw, zwe, Zimbabwe, AFRICA, EASTAFRICA" },
  { "🇬🇳", "🇬🇳: gn, gin, Guinea, AFRICA, WESTAFRICA" },
  { "🇷🇪", "🇷🇪: re, reu, Réunion, reunion, FRANCE, AFRICA, EASTAFRICA" }, // Réunion
  { "🇷🇼", "🇷🇼: rw, rwa, Rwanda, AFRICA, EASTAFRICA" },
  { "🇧🇯", "🇧🇯: bj, ben, Benin, AFRICA, WESTAFRICA" },
  { "🇧🇮", "🇧🇮: bi, bdi, Burundi, AFRICA, EASTAFRICA" },
  { "🇹🇳", "🇹🇳: tn, tun, Tunisia, AFRICA, NORTHAFRICA" },
  { "🇹🇬", "🇹🇬: tg, tgo, Togo, AFRICA, WESTAFRICA" },
  { "🇸🇱", "🇸🇱: sl, sle, SierraLeone, AFRICA, WESTAFRICA" }, // Sierra Leone
  { "🇨🇩", "🇨🇩: cd, cod, Congo, AFRICA, CENTRALAFRICA" },
  { "🇨🇫", "🇨🇫: cf, caf, CentralAfrican, CENTRALAFRICA" }, // Central African Republic
  { "🇱🇷", "🇱🇷: lr, lbr, Liberia, AFRICA, WESTAFRICA" },
  { "🇲🇷", "🇲🇷: mr, mrt, Mauritania, AFRICA, WESTAFRICA" },
  { "🇪🇷", "🇪🇷: er, eri, Eritrea, AFRICA, EASTAFRICA" },
  { "🇬🇲", "🇬🇲: gm, gmb, Gambia, AFRICA, WESTAFRICA" },
  { "🇧🇼", "🇧🇼: bw, bwa, Botswana, AFRICA, SOUTHAFRICA" },
  { "🇳🇦", "🇳🇦: na, nam, Namibia, AFRICA, SOUTHAFRICA" },
  { "🇬🇦", "🇬🇦: ga, gab, Gabon, AFRICA, CENTRALAFRICA" },
  { "🇱🇸", "🇱🇸: ls, lso, Lesotho, AFRICA, SOUTHAFRICA" },
  { "🇬🇼", "🇬🇼: gw, gnb, GuineaBissau, AFRICA, WESTAFRICA" }, // Guinea-Bissau
  { "🇬🇶", "🇬🇶: gq, gnq, EquatorialGuinea, CENTRALAFRICA" }, // Equatorial Guinea
  { "🇲🇺", "🇲🇺: mu, mus, Mauritius, AFRICA, EASTAFRICA" },
  { "🇲🇺", "🇲🇺: mz, moz, Mozambique, AFRICA, EASTAFRICA" },
  { "🇸🇿", "🇸🇿: sz, swz, Eswatini, AFRICA, SOUTHAFRICA" },
  { "🇩🇯", "🇩🇯: dj, dji, Djibouti, AFRICA, EASTAFRICA" },
  { "🇰🇲", "🇰🇲: km, com, Comoros, AFRICA" },
  { "🇨🇻", "🇨🇻: cv, cpv, CapeVerde, AFRICA, WESTAFRICA" },
  { "🇪🇭", "🇪🇭: eh, esh, WesternSahara, SPAIN, AFRICA, NORTHAFRICA" }, // Western Sahara
  { "🇸🇹", "🇸🇹: st, stp, SãoToméandPríncipe, saotomeandprincipe, CENTRALAFRICA" }, // São Tomé and Príncipe
  { "🇸🇨", "🇸🇨: sc, syc, Seychelles, AFRICA, EASTAFRICA" },
  { "🇸🇭", "🇸🇭: sh, shn, TristandaCunha, UK" }, // Tristan cunha
  { "🇦🇺", "🇦🇺: au, aus, Australia, AUSTRALASIA, OCEANIA" },
  { "🇨🇽", "🇨🇽: cx, cxr, Christmasisland, AUSTRALIA" }, // Christmas Island
  { "🇨🇨", "🇨🇨: cc, cck, CocosIslands, AUSTRALIA" }, // Cocos (Keeling) Islands
  { "🇮🇲", "🇮🇲: im, imn, ManIsle, UK" }, // Isle of Man
  { "🇰🇮", "🇰🇮: ki, kir, Kiribati, MICRONESIA, OCEANIA" },
  { "🇳🇷", "🇳🇷: nr, nru, Nauru, MICRONESIA, OCEANIA" },
  { "🇳🇨", "🇳🇨: nc, ncl, NewCaledonia, FRANCE, OCEANIA" }, // New Caledonia
  { "🇫🇯", "🇫🇯: fj, fji, Fiji, MELANESIA, OCEANIA" },
  { "🇫🇲", "🇫🇲: fm, fsm, Micronesia, MICRONESIA, OCEANIA" },
  { "🇵🇬", "🇵🇬: pg, png, PapuanewGuinea, MELANESIA, OCEANIA" }, // Papua New Guinea
  { "🇻🇺", "🇻🇺: vu, vut, Vanuatu, MELANESIA, OCEANIA" },
  { "🇸🇧", "🇸🇧: sb, slb, SolomonIslands, MELANESIA, OCEANIA" }, // Solomon Islands
  { "🇬🇺", "🇬🇺: gu, gum, Guam, USA, MICRONESIA, OCEANIA" },
  { "🇲🇭", "🇲🇭: mh, mhl, MarshallIslands, MICRONESIA, OCEANIA" }, // Marshall Islands
  { "🇲🇵", "🇲🇵: mp, mnp, NorthernMariana, MICRONESIA, OCEANIA" }, // Northern Mariana Islands
  { "🇵🇫", "🇵🇫: pf, pyf, FrenchPolynesia, FRANCE, POLYNESIA, OCEANIA" }, // French Polynesia
  { "🇼🇸", "🇼🇸: ws, wsm, Samoa, POLYNESIA, OCEANIA" },
  { "🇼🇫", "🇼🇫: wf, wlf, WallisandFutuna, FRANCE, OCEANIA" }, // Wallis and Futuna
  { "🇹🇻", "🇹🇻: tv, tuv, Tuvalu, OCEANIA" },
  { "🇦🇸", "🇦🇸: as, asm, Americansamoa, USA, POLYNESIA, OCEANIA" }, // American Samoa
  { "🇵🇳", "🇵🇳: pn, pcn, Pitcairn, UK, POLYNESIA, OCEANIA" }, // Pitcairn Islands
  { "🇵🇼", "🇵🇼: pw, plw, Palau, MICRONESIA, OCEANIA" },
  { "🇯🇪", "🇯🇪: je, jey, Jersey, FRANCE" },
  { "🇦🇶", "🇦🇶: aq, ata, Antarctica, ANTARCTICA" },
  { "🇳🇫", "🇳🇫: nf, nfk, NorFolkIsland, AUSTRALASIA, POLYNESIA, OCEANIA" }, // Norfolk Island
  { "🇨🇰", "🇨🇰: ck, cok, Cookisland, NEWZEALAND, POLYNESIA, OCEANIA" }, // Cook Islands
  { "🇳🇿", "🇳🇿: nz, nzl, NewZealand, NEWZEALAND, AUSTRALASIA, OCEANIA" }, // New Zealand
  { "🇳🇺", "🇳🇺: nu, niu, Niue, NEWZEALAND, POLYNESIA, OCEANIA" },
  { "🇹🇰", "🇹🇰: tk, tkl, Tokelau, NEWZEALAND, POLYNESIA, OCEANIA" },
  { "🇹🇴", "🇹🇴: to, ton, Tonga, POLYNESIA, OCEANIA" },
  
  // still missing
  
  { "🇮🇴", "🇮🇴: io, iot, BritishIndianOcean" }, // British Indian Ocean Territory
  { "🇹🇫", "🇹🇫: tf, atf, FrenchSouthernandaAtarctic" }, // French Southern and Antarctic Lands
  { "🇬🇬", "🇬🇬: gg, ggy, Guernsey, GUERNSEY" },
  { "🇭🇲", "🇭🇲: hm, hmd, HeardandMacDonaldsIslands" }, // Heard Island and McDonald Islands
  { "🇺🇲", "🇺🇲: um, umi, UsMinorOutlyingIslands, US" }, // United States Minor Outlying Islands
};

Tässä on kasaan koottu mallikeskustelu mr8:n kanssa vapaasti

'xmldoctype'= "html"

Väliaika, lisätään lokit ressu2:n, tämänhetkinen sorsa:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>

#include <sys/time.h>
#include <time.h>

#define MAIN 2

unsigned char *procname;
static unsigned char *programname = "Ressu3 version 1.00 ©";
static unsigned char *copyright = "Copyright (c)1998-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";
//static unsigned char *copyright = "Copyright (c)2013-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";
int my_output = 0;

void my_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
  int c;

  if(my_output) {
    fprintf(stdout,"\n");
    my_output = 0;
  }
  for(c = 0; c < len; c++) {
    if(c % linelen == 0) {
      if(c > 0)
	fprintf(stdout,"\n");
      fprintf(stdout,"%-10s", header);
    }
    fprintf(stdout," %02x", buf[c]);
  }
  fprintf(stdout,"\n");
  fflush(stdout);
}

#define DEBUG8 2

#define USE_URANDOM 2
#define USE_RESSU3 2
#define USE_PSEUDORESSU3 2
#define USE_RESSU3TWIST 2
#define aUSE_RESSU3LOGS 2
#define USE_RESSU3COMMANDS 2


#if defined USE_RESSU3 || defined USE_PSEUDORESSU3 || defined USE_RESSU3TWIST

static unsigned long long my_ressu_useconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}

static unsigned char my_ressu_lowusec() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

static int randomness = 0;

#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )

static void my_ressu3_round(int size, unsigned char *buffer) // ressu JariK 2013, 2025
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = my_ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	randomness++;
      }
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + 16 + buffer[d] + 2) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = my_ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

#include "newressu.h"

#define RESSU3_BYTES 2048 // now 2048
#define RESSU3_RANDOMNESS_NEEDED 2048 // now 2048 
#define RESSU3_CLOCKS_NEEDED 20480 // now 20480
#define RESSU3_MINIMUM_ROUNDS 5 // now 5

void my_ressu3_bytes(int size, unsigned char *buffer) // Ressu3 v1.1 JariK 2013, 2025, 2026
{
  int c, d, clocksused;
  static int ressu_pos = 0, initneeded = 1;
  static unsigned char ressu[RESSU3_BYTES];
  
  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      if(initneeded) {
	memset(&ressu, 0, sizeof(ressu));
	initneeded = 0;
      }
      randomness = 0;
      clocksused = 0;
      //memset(&ressu, 0, sizeof(ressu));
      
      for(d = 0; d < RESSU3_MINIMUM_ROUNDS ||
	    randomness < RESSU3_RANDOMNESS_NEEDED ||
	    clocksused < RESSU3_CLOCKS_NEEDED
	    ; d++) {
	my_ressu3_round(sizeof(ressu), ressu);
	clocksused += (sizeof(ressu) * 8);
      }
      
#ifdef DEBUG8
      my_dump("myressu3g", sizeof(ressu), ressu, 32);      
#endif
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  my_dump("myressu3", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_RESSU3 || defined USE_PSEUDORESSU3 || defined USE_RESSU3TWIST

#if defined USE_PSEUDORESSU3 || defined USE_RESSU3TWIST

unsigned char cvar[16];
int cvarsize = 0;

void inccvar()
{
  int c;

  /* 16 bytes, LSB first */
  for(c = 0; ++cvar[c] == 0 && c < sizeof(cvar) - 1; c++);

  if(cvarsize < c)
    cvarsize = c;

#ifdef DEBUG20
  ressu_dump("cvar", cvarsize + 1, cvar, 32);
#endif
}

void clearcvar()
{
  int c;

  cvarsize = 0;
  
  for(c = 0; c < sizeof(cvar); c++)
    cvar[c] = 0;

  for(c = 0; c < sizeof(cvar); c++)
    if(cvar[c] != 0)
      cvarsize = c;
}

#include "sha256.h"

#define PSEUDORESSU3_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU3_TOPUP_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU3_TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define PSEUDORESSU3_TOPUP_TWICE 2 // off by default

static unsigned char pseudoressu3_key[HashLen]; // 32 bytes, 256 bits

static void my_pseudoressu3_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu3_key, sizeof(pseudoressu3_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu3_addrandomness(int size, unsigned char *buffer)
{
  unsigned long long usec;
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu3_key, sizeof(pseudoressu3_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  usec = my_ressu_useconds(); // add timestamp to hash
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  usec = clock(); // add processor time to hash (for randomness)
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  HashUpdate(&hash, buffer, size); // add given randomness to hash
  HashFinal(pseudoressu3_key, &hash); // save as new key
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu3_topup()
{
  unsigned char topup[PSEUDORESSU3_TOPUP_SIZE]; // 32 bytes, 256 bits

  memset(&topup, 0, sizeof(topup)); // forget topup
  my_ressu3_bytes(sizeof(topup), topup);
#ifdef DEBUG8
  my_dump("topup", sizeof(topup), topup, 32);
#endif
  my_pseudoressu3_addrandomness(sizeof(topup), topup);

  memset(&topup, 0, sizeof(topup)); // forget topup
}

void my_pseudoressu3_bytes(int size, unsigned char *buffer) // JariK 2022, 2025
{
  int c;
  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
  static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudoressu_pos == 0) {
      if(topup_counter == 0) {
	if(initneeded) {
	  my_ressu3_bytes(sizeof(pseudoressu3_key), pseudoressu3_key); // get first key
#ifdef DEBUG8
	  my_dump("first key", sizeof(pseudoressu3_key), pseudoressu3_key, 32);
#endif
	  initneeded = 0;
	} // end of if(initneeded
	
	my_pseudoressu3_topup(); // add randomness to key, first block also
#ifdef PSEUDORESSU3_TOPUP_TWICE
	my_pseudoressu3_topup(); // add randomness to key, first block also
#endif
	topup_counter = PSEUDORESSU3_TOPUP_BYTES;
      } // end of if(topup_counter == 0
      
      my_pseudoressu3_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
      my_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
      topup_counter -= sizeof(pseudoressu);
    } // end of if(pseudoressu_pos == 0

    buffer[c] ^= pseudoressu[pseudoressu_pos];
    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
  } // end of for(c = 0; c < size; c++
  
  my_pseudoressu3_internalbytes(pseudoressu3_key); // replace key with new random one
#ifdef DEBUG8
  my_dump("new key", sizeof(pseudoressu3_key), pseudoressu3_key, 32);
#endif
#ifdef DEBUG8
  my_dump("pseudoressu", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_PSEUDORESSU3 || defined USE_RESSU3TWIST

#ifdef USE_RESSU3TWIST

void my_ressu3twist_bytes(int size, unsigned char *buffer) // JariK 2023, 2025
{
  //urandom_bytes(size, buffer);
  my_ressu3_bytes(size, buffer);
  my_pseudoressu3_bytes(size, buffer);
#ifdef DEBUG8
  my_dump("ressu3twist", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_RESSU3TWIST

#ifdef USE_URANDOM

void my_readfile_xor(int size, unsigned char *buffer, unsigned char *filename)
{
  int c, n, filebuffer_pos = 0;
  unsigned char filebuffer[64];
  FILE *fp1;

  if((fp1 = fopen(filename, "rb")) == NULL) {
    fprintf(stderr,"%s: fopen(): cannot open file %s\n",
	    procname, filename);
    exit(1);
  }

  for(c = 0; c < size; c++) {
    if(filebuffer_pos == 0) {
      n = (size - c < sizeof(filebuffer)) ? size - c : sizeof(filebuffer);
      if(fread(filebuffer, 1, n, fp1) < n) {
	fprintf(stderr,"%s: fread(): cannot read file %s\n",
		procname, filename);
	exit(1);
      }
#ifdef DEBUG8
      my_dump("file", n, filebuffer, 32);
#endif
    } // end of if(file_pos == 0
    buffer[c] ^= filebuffer[filebuffer_pos];
    filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);
  } // end of for(c = 0; c < size; c++

  fclose(fp1);

  memset(filebuffer, 0, sizeof(filebuffer)); // forget file
}

static unsigned char urandomfilename[128] = "/dev/urandom";

void my_urandom_bytes(int size, unsigned char *buffer)
{
  //static my_readfile_xor(int size, unsigned char *buffer, unsigned char *urandom_filename);
#ifdef DEBUG8
  my_dump("urandom", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_URANDOM

#ifdef USE_RESSU3LOGS
#endif

#ifdef USE_RESSU3COMMANDS

void my_readcommand_xor(int size, unsigned char *buffer, unsigned char *commandname)
{
  int c, n, commandbuffer_pos = 0;
  unsigned char commandbuffer[64];
  FILE *fp1;

  if((fp1 = fopen(commandname, "rb")) == NULL) {
    fprintf(stderr,"%s: fopen(): cannot open command %s\n",
	    procname, commandname);
    exit(1);
  }

  for(c = 0; c < size; c++) {
    if(commandbuffer_pos == 0) {
      n = (size - c < sizeof(commandbuffer)) ? size - c : sizeof(commandbuffer);
      if(fread(commandbuffer, 1, n, fp1) < n) {
	fprintf(stderr,"%s: fread(): cannot read command %s\n",
		procname, commandname);
	exit(1);
      }
#ifdef DEBUG8
      my_dump("command", n, commandbuffer, 32);
#endif
    } // end of if(command_pos == 0
    buffer[c] ^= commandbuffer[commandbuffer_pos];
    commandbuffer_pos = (commandbuffer_pos + 1) % sizeof(commandbuffer);
  } // end of for(c = 0; c < size; c++

  fclose(fp1);

  memset(commandbuffer, 0, sizeof(commandbuffer)); // forget command
}

static unsigned char command[128] = "echo abcd";

void my_command_bytes(int size, unsigned char *buffer)
{
  my_readcommand_xor(int size, unsigned char *buffer, unsigned char *commandname);
#ifdef DEBUG8
  my_dump("command", size, buffer, 32);
#endif
}

#endif // USE_RESSU3COMMANDS


void my_random_bytes(int size, unsigned char *buffer)
{
#ifdef USE_URANDOM
  my_urandom_bytes(size, buffer);
#endif

#ifdef USE_RESSU3COMMANDS
  my_command_bytes(size, buffer);
#endif

  //#ifdef USE_RESSU3LOGS
  //void my_ressu3logs(int size, unsigned char *buffer, "echo abcd");
  //void my_ressu3logs(int size, unsigned char *buffer, "tail *.lo | grep "thisday"));
  //void my_ressu3logs(int size, unsigned char *buffer, "newressusudoku"));
  //void my_ressu3logs(int size, unsigned char *buffer, "newressu"));
  //#endif // USE_RESSU3LOGS

  //ressu_round(size, buffer);
  //ressu_genbytes(size, buffer);
  //pseudoressu_bytes(size, buffer);
  //ressutwist_bytes(size, buffer);
  //my_ressu3_round(size, buffer);
#ifdef USE_PSEUDORESSU3
  my_pseudoressu3_bytes(size, buffer);
#endif
#ifdef USE_RESSU3TWIST
  my_ressu3twist_bytes(size, buffer);
#endif
#ifdef USE_RESSU3
  my_ressu3_bytes(size, buffer);
#endif
}

#define GENT_SIZE 128

static unsigned char gent[GENT_SIZE];
static unsigned int gent_pos = 0;

int my_random_byte()
{
  unsigned char ch;
  static int initneeded = 1;

  if(gent_pos == 0) {
    if(initneeded) {
      memset(&gent, 0, sizeof(gent));
      initneeded = 0;
    }
    my_random_bytes(sizeof(gent), gent);
  }
  ch = gent[gent_pos];
  gent_pos = (gent_pos + 1) % sizeof(gent);

  return(ch);
}

unsigned long my_random_genlimit(unsigned long limit)
{
  int c;
  unsigned long word;
  static unsigned long lastlimit = 0, highlimit;
  static int bytes;
  
  if(lastlimit != limit) { // if limit changes, calculate new highlimit and bytes
    lastlimit = limit;
    if(limit <= 0x100) {
      // highest multiplier of limit that fits to needed bytes
      highlimit = (0x100 / limit) * limit;
      // number of bytes needed
      bytes = 1;
    } else if(limit <= 0x10000) {
      highlimit = (0x10000 / limit) * limit;
      bytes = 2;
    } else if(limit <= 0x1000000) {
      highlimit = (0x1000000 / limit) * limit;
      bytes = 3;
    } else if(limit <= 0x100000000) {
      highlimit = (0x100000000 / limit) * limit;
      bytes = 4;
    } else if(limit <= 0x10000000000) {
      highlimit = (0x10000000000 / limit) * limit;
      bytes = 5;
    } else if(limit <= 0x1000000000000) {
      highlimit = (0x1000000000000 / limit) * limit;
      bytes = 6;
    } else if(limit <= 0x100000000000000) {
      highlimit = (0x100000000000000 / limit) * limit;
      bytes = 7;
    } else { // if(limit <= 0xffffffffffffffff) {
      highlimit = (0xffffffffffffffff / limit) * limit;      
      bytes = 8;
    }
  } // if(lastlimit != limit)

  for(;;) {
    word = 0;
    for(c = 0; c < bytes; c++)
      word = word << 8 | my_random_byte();
    if(word < highlimit)
      break;
  }

  word %= limit;
  
  return(word);
}

void ressu3_version()
{
  fprintf(stderr, "%s", programname); // touch these outside #ifdef MAIN
  fprintf(stderr, ", %s, Finland, Ei johdannaisia", copyright);
}

#include <sys/ioctl.h> // for TIOCGWINSZ

#ifdef MAIN

int main(int argc, char *argv[])
{
  int c, d;

  procname = argv[0];

  //
  // look thru command line parameters
  //

  for(c = 1; c < argc; c++) {
    if(!strcmp("--copyright", argv[c]) ||
       !strcmp("--version", argv[c])) {
      ressu3_version();
#ifdef SHA256
      fprintf(stderr,"\nsha256(");
      for(int c = 0; c < HashLen; c++) {
	fprintf(stderr, "%02x", programfiledigest[c]);
      }
#endif // end of #ifdef SHA256

    }
  }

  for(c = 0; c < 10; c++) {
    fprintf(stdout, "%05x", c);
    my_output = 1;
    for(d = 0; d < 32; d++) {
      fprintf(stdout, " ");
      fprintf(stdout, "%02llx", (unsigned long long) my_random_genlimit(0x100));
    }
    fprintf(stdout,"\n");
  }
}
#endif // end of #ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <sys/time.h>
#include <math.h>
#include <sys/types.h>

//#define SHA256 2 // in Makefile

#include "sha256.h"
#include "cvar.h"

//#define MAIN 2 // in Makefile

extern unsigned char *procname;
static unsigned char *programname = "Newressu version 4.11 ©";
static unsigned char *copyright = "Copyright (c) 1998-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";

int newressu_output = 0;

void ressu_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
  int c;

  if(newressu_output) {
    fprintf(stdout,"\n");
    newressu_output = 0;
  }
  for(c = 0; c < len; c++) {
    if(c % linelen == 0) {
      if(c > 0)
	fprintf(stdout,"\n");
      fprintf(stdout,"%-10s", header);
    }
    fprintf(stdout," %02x", buf[c]);
  }
  fprintf(stdout,"\n");
  fflush(stdout);
}

static unsigned long periods[1024];
static unsigned long genbytes = 0;
static unsigned long clockbytes = 0;

int verbose = 0;
int size = -1, type = 10;

#define USE_RANDOM 2

#define ALL_SLICE 16 // 16 // orig 64
#define RESSUT_SLICES 128 // 128 // orig 32
#define RESSUT_BYTES (RESSUT_SLICES * ALL_SLICE) // 2048 16 * 128 // (32 * 64)

#define RESSU_MIN_ROUNDS 2
#define RESSU_MIN_CLOCKBYTES 16 * 1024

#define GENT_SLICES 128 // 32 // orig 16
#define GENT_SIZE (GENT_SLICES * ALL_SLICE) // 1024 (16 * 64)

static int ressut_bytes = (RESSUT_SLICES * ALL_SLICE); // orig 2048
static int ressut_bits1_needed = RESSUT_SLICES * 2; // orig 256
static int ressut_bits2_needed = RESSUT_SLICES * 8; // orig 1024
static int ressut_bits3_needed = RESSUT_SLICES * 16; // orig 2048
static int ressut_bits4_needed = RESSUT_SLICES * 16; // orig 2048
static int ressut_bits5_needed = RESSUT_SLICES * 16; // orig 2048
static int ressut_bits6_needed = RESSUT_SLICES * 32; // orig 2048 * 2
static int ressut_bits7_needed = RESSUT_SLICES * 128; // orig 2048 * 8
static int ressut_bits20_needed = RESSUT_SLICES * 32; // orig 2048 * 2
static int ressut_bits21_needed = RESSUT_SLICES * 16; // orig 2048
static int ressut_bits30_needed = RESSUT_SLICES * 32; // orig 2048 * 2

int rndbits1 = 0,
  rndbits2 = 0,
  rndbits3 = 0,
  rndbits4 = 0,
  rndbits5 = 0,
  rndbits6 = 0,
  rndbits7 = 0,
  rndbits20 = 0,
  rndbits21 = 0,
  rndbits22 = 0,
  rndbits30 = 0;

static int stats = 0;

#define DEBUG_SORTED 2

unsigned long long ressu_useconds2()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((unsigned long long)tv.tv_usec + 1000000ULL * (unsigned long long)tv.tv_sec);
}

static unsigned char ressu_lowusec2() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

#define FIXEDCLOCKCHAINLENGTH 50 // orig 50
unsigned int fixedclockchainlength = FIXEDCLOCKCHAINLENGTH;

int fixedclock = 0; // 0 = normal, 1 = fixed

static unsigned char ressu_clock()
{
  static unsigned int clockbyte = 0, counter = 0;

  if(!fixedclock)
    return ressu_lowusec2();
  else {
    if(counter == 0) {
      clockbyte++;
      counter += fixedclockchainlength;
    }
    counter--;
    return(clockbyte & 0xff);
  }
}

#include <sys/types.h>
#include <unistd.h>

#define aDEBUG2A 2
#define aDEBUG2B 2
#define aDEBUG2C 2
#define aDEBUG2D 2
#define aDEBUG2E 2
#define aDEBUG2F 2
#define aDEBUG2G 2
#define aDEBUG2H 2

static unsigned char *ressuct; // ressu random buffer lookup
static unsigned int ressuct_bytes;
static unsigned char ch;

#ifdef DEBUG2H

unsigned long count[RESSUT_BYTES];

#endif

static unsigned int ressu_nonrandom() // not really random
{
  static unsigned int rando = 0;
  struct timeval tv;

  int pid = getpid();
  int clock2 = clock();
  gettimeofday(&tv, NULL);

#ifdef DEBUG2G

  static int rowid = 0;

  if(rowid == 0) {
    fprintf(stdout,"%6s","rowid");
    fprintf(stdout,"%6s","rando");
    fprintf(stdout,"%6s","pid");
    fprintf(stdout,"%6s","clk");
    fprintf(stdout,"%6s","dtime");
    fprintf(stdout,"%6s","+usec");
    fprintf(stdout,"%6s","ptime");
    fprintf(stdout,"%6s","+usec");
    fprintf(stdout,"%6s","ch*ch");
    fprintf(stdout,"%6s","newra");
    fprintf(stdout,"\n");
  }
  fprintf(stdout,"%6d", rowid++);
  fprintf(stdout,"%6d", rando % RESSUT_BYTES);

#endif
  
  rando = rando +
    //genbytes +
    //time(NULL) +
    //ressu_useconds2() +
    //ressu_clock() +
    //buf.tms_utime + 
    //buf.tms_stime +
    pid +
    clockbytes +
    tv.tv_sec +
    tv.tv_usec +
    clock2 / CLOCKS_PER_SEC +
    clock2 % CLOCKS_PER_SEC +
    ch * ch;

#ifdef DEBUG2G
  
  fprintf(stdout,"%6d", pid % RESSUT_BYTES);
  fprintf(stdout,"%6d", (int) clockbytes %RESSUT_BYTES);
  fprintf(stdout,"%6d", (int) tv.tv_sec % RESSUT_BYTES);
  fprintf(stdout,"%6d", (int) tv.tv_usec % RESSUT_BYTES);
  fprintf(stdout,"%6d", (int) (clock2 / CLOCKS_PER_SEC) % RESSUT_BYTES); 
  fprintf(stdout,"%6d", (int) (clock2 % CLOCKS_PER_SEC) % RESSUT_BYTES);
  fprintf(stdout,"%6d", (int) (ch * ch) % RESSUT_BYTES);
  fprintf(stdout,"%6d", rando % RESSUT_BYTES);
  fprintf(stdout,"\n");

#endif
  
#ifdef DEBUG2H
  count[rando % ressuct_bytes]++;
#endif
  
#if defined DEBUG2C && !defined DEBUG2G
  static unsigned int itemnum = 0;
  
  if(itemnum % 16 == 0) {
    if(itemnum > 0)
      fprintf(stdout,"\n");
    fprintf(stdout,"%05d ", itemnum);
  }
  fprintf(stdout," %4u", rando % ressuct_bytes);
  itemnum++;
  newressu_output = 1;
#endif

  return(rando);
}

#define MAX_DEPTH 4 // now 4

int depth = 4; // now 4

unsigned int copyreverse = 1;
unsigned long cblocks = 0;
unsigned char lens = 4;

static unsigned char ressu_copyreverse(int pdepth) // 2024 JariK
{
  static int reverse[MAX_DEPTH] = {0}; // 0 = copy, 1 = reverse, 28.10.2022 JariK
  static unsigned int len[MAX_DEPTH] = {0};
  static unsigned int count[MAX_DEPTH] = {0};
  static unsigned int low[MAX_DEPTH] = {0};
  static unsigned int high[MAX_DEPTH] = {0};
  static unsigned char bytes[MAX_DEPTH][257] = {0};
  
  if(pdepth == 0) {
#ifdef DEBUG2D
    int c = ressu_clock();
    //fprintf(stdout,", ch2:%02x",c);
    return(c);
#else
    return(ressu_clock());
#endif
  }

  pdepth--;

  // dividing clock stream into blocks
  // and reversing every other block

  // copy next block to bytes
  
  if(count[pdepth] == 0) { // previous block ended
    reverse[pdepth] = !reverse[pdepth];
    len[pdepth] = ressuct[ressu_nonrandom() % ressuct_bytes] + 2; // block size
    //len[pdepth] = (ressuct[ressu_nonrandom() % ressuct_bytes] & 3 ) + 2; // block size
    //len[pdepth] = --lens + 2; // block size
    //len[pdepth] = lens++ + 2; // block size
    count[pdepth] = len[pdepth];
    low[pdepth] = 0;
    high[pdepth] = len[pdepth];
    rndbits2 += 2;
#ifdef DEBUG2A
    fprintf(stdout,"\nblk:");
    fprintf(stdout," depth:%d", pdepth);
    fprintf(stdout,", reverse:%d", reverse[pdepth]);
    fprintf(stdout,", len:%d", len[pdepth]);
    fprintf(stdout,", count:%d", count[pdepth]);
    fprintf(stdout,", low:%d", low[pdepth]);
    fprintf(stdout,", high:%d", high[pdepth]);
    fflush(stdout);
#endif
    for(int c = 0; c < len[pdepth]; c++) {
      bytes[pdepth][c] = ressu_copyreverse(pdepth); // block bytes
#ifdef DEBUG2A
      fprintf(stdout,", b%d:%02x", pdepth, bytes[pdepth][c]);
      newressu_output = 1;
#endif
    }
  }
  if(reverse[pdepth]) { // reverse
    
    // get reversed byte to return
    ch = bytes[pdepth][--high[pdepth]]; // reverse
#ifdef DEBUG2E
    fprintf(stdout,", rev%d:%02x", pdepth, ch);
    fflush(stdout);
#endif
    --count[pdepth];

  } else { // copy
    
    // get copied byte to return
    ch = bytes[pdepth][low[pdepth]++]; // copy
#ifdef DEBUG2E
    fprintf(stdout,", copy%d:%02x", pdepth, ch);
    fflush(stdout);
#endif
    --count[pdepth];
  }

  return(ch);
}

static unsigned char ressu_clockbyte() /* JariK 2013 */
{
  if(copyreverse) {
    ch = ressu_copyreverse(depth);
  } else {
    ch = ressu_clock();
  } // end of if(copyreverse)

#ifdef DEBUG2F
  static unsigned int cols = 0;
  if(cols % 32 == 0) {
    if(cols > 0)
      fprintf(stdout,"\n");
    fprintf(stdout,"%05u ",cols);
    newressu_output = 1;
  }
  if(cols % 4 == 0)
    fprintf(stdout," ");
  fprintf(stdout,"%02x",ch);
  newressu_output = 1;
  cols++;
#endif
  
  // statistics for theoretical
  // random bits calculation (rndbits?)
  
  static int prevbyte = -1, clockcount = 0;
  static int prevclockcount = -1;
  
  if(prevbyte == -1)
    prevbyte = ch;
  if(prevbyte != ch) {
    periods[clockcount]++;
    clockbytes += clockcount;
#ifdef DEBUG2B
    fprintf(stdout," %d", clockcount);
    newressu_output = 1;
#endif
    if((ch & 1) != (prevbyte & 1))
      rndbits20++;
    if((ch & 2) != (prevbyte & 2))
      rndbits21++;
    if((ch & 4) != (prevbyte & 4))
      rndbits22++;

    if(prevclockcount == -1)
      prevclockcount = clockcount;
    
    if(((ch & 1) != (prevbyte & 1)) && prevclockcount != clockcount)
      rndbits30++;
    
    prevclockcount = clockcount;

    clockcount = 0;

    prevbyte = ch;
  }
  clockcount++;
  
  return(ch);
}

#define RR8(byte, bits) ( ((byte) >> (bits)) | ((byte) << (8 - (bits))) )
#define RL8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )

#define aDEBUG5A 2
#define aDEBUG5B 2
#define aDEBUG5C 2
#define aLOWCLOCKBITONLY 2 // off by default

void ressu_genbytes_single_do(int size, unsigned char *buffer) // JariK 2013
{
  int c, d;
  unsigned char e;
  static int f = 0;
  
  for(c = 0; c < 8; c++) {
    for(d = 0; d < size; d++) { // shift and xor
      e = buffer[d];
      e = RL8(e, 1); // rotate byte left 1 bits
      //e = RL8(e, 3); // rotate byte left 3 bits
      //e = RR8(e, 1); // rotate byte right 1 bits

#ifdef LOWCLOCKBITONLY
      buffer[d] = e ^ (ressu_clockbyte() & 1);
#else
      buffer[d] = e ^ ressu_clockbyte();
#endif
    }
    for(d = 0; d < size; d++) { // swap
#ifdef DEBUG5B
      fprintf(stdout,"d:%d", d);
      fprintf(stdout,", f:%d", f);
      fprintf(stdout,", bufferd:%d", buffer[d]);
      fprintf(stdout,", bufferf:%d", buffer[f]);
      fprintf(stdout,"\n");
#endif
      f = (f + buffer[d] + 2) % size; // + 2 JariK 2022
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }

    // more randomness from clocks. JariK 2025

    unsigned long long usec;
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = ressu_useconds2();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  }
}

void ressu_genbytes_single(int size, unsigned char *buffer)
{
  ressuct = buffer;  // ressu random buffer lookup
  ressuct_bytes = size;

  rndbits2 = 0;
  clockbytes = 0;

  cblocks = 0;

  ressu_genbytes_single_do(size, buffer);

  //
  //  display statistics
  //

  if(stats) {

    if(newressu_output == 1)
      fprintf(stdout, "\n");
    newressu_output = 0;

    fprintf(stderr, "rounds:1");

    long chains = 0;
    
    for(int e = 0; e < 1024; e++) {
      if(periods[e] > 0) {
	fprintf(stderr, " %d:%lu", e, periods[e]);
	chains += periods[e];
      }
    }
    
    fprintf(stderr, ", chains:%ld", chains);
    fprintf(stderr, ", blocks:%ld", cblocks);
    fprintf(stderr, ", clockbytes:%ld", clockbytes);
    fprintf(stderr, ", rndbits2:%d", rndbits2);
    fprintf(stderr, "\n");
    fflush(stderr);
  }
#ifdef DEBUG7

  ressu_dump("single", size, buffer, 32);

#endif
  
  genbytes += size;
}

void ressu_genbytes_fast(int size, unsigned char *buffer)
{
  int d, e, f;

  ressuct = buffer; // ressu random buffer lookup
  ressuct_bytes = size;

  rndbits2 = 0;
  clockbytes = 0;

  cblocks = 0;
  
  for(d = 0; d < RESSU_MIN_ROUNDS ||
	(copyreverse == 1 && depth > 0 && rndbits2 < ressut_bits2_needed) ||
	clockbytes < RESSU_MIN_CLOCKBYTES; d++) {
    ressu_genbytes_single_do(size, buffer);
  }

  //
  //  display statistics
  //
  
  if(stats) {

    if(newressu_output == 1)
      fprintf(stdout, "\n");
    newressu_output = 0;

    fprintf(stderr, "rounds:%d", d);

    long chains = 0;
    
    for(e = 0; e < 1024; e++) {
      if(periods[e] > 0) {
	fprintf(stderr, " %d:%lu", e, periods[e]);
	chains += periods[e];
      }
    }

    fprintf(stderr, ", chains:%ld", chains);
    fprintf(stderr, ", blocks:%ld", cblocks);
    
#ifdef DEBUG_SORTED
    
    fprintf(stderr, ", sorted:");

    int g = 0;

    for(;;) {
      f = -1;
      for(e = 0; e < 1024; e++) {
	if( (f == -1 && periods[e] > g) ||
	    (periods[e] > g && f > periods[e]) )
	  f = periods[e];
      }
      if(f == -1)
	break;
      
      g = f;
      fprintf(stderr," %d", g);
    }
    
#endif
    
    fprintf(stderr, ", clockbytes:%ld", clockbytes);
    fprintf(stderr, ", rndbits2:%d", rndbits2);
    fprintf(stderr, "\n");
    fflush(stderr);
  }

#ifdef DEBUG7

  ressu_dump("fast", size, buffer, 32);

#endif
  
  genbytes += size;
}

#define aDEBUG3B 2
#define aDEBUG8 2

void ressu_genbytes(int size, unsigned char *buffer) // 6.5.2021 JariK
{
  int c, d, e, f;
  static unsigned char ressut[RESSUT_BYTES];
  static int ressut_first = 1,
    ressut_pos = 0;

  unsigned long prevperiods[1024];

  ressuct = ressut;  // ressu random buffer lookup
  ressuct_bytes = ressut_bytes; // table used in ressu_genbytes_single_do

  for(c = 0; c < size; c++) {
    if(ressut_pos == 0) {
      if(ressut_first) {
	memset(ressut, 0, ressut_bytes);
	ressut_first = 0;
      }

      clockbytes = 0;
      for(d = 0; d < 1024; d++) {
	periods[d] = 0;
      }

      rndbits1 = 0;
      rndbits2 = 0;
      rndbits3 = 0;
      rndbits4 = 0;
      rndbits5 = 0;
      rndbits6 = 0;
      rndbits7 = 0;
      rndbits20 = 0;
      rndbits21 = 0;
      rndbits22 = 0;
      rndbits30 = 0;

      cblocks = 0;
      
      int lim, lim1 = 0, lim2 = 0;
      int lim1a, lim1b;
      int high1, high2;

      int rndbits3high;
      int rndbits4highdigits;
      int rndbits6high;
      int rndbits6pos;
      int rndbits7high;
      
      for(d = 0;
	  rndbits1 < ressut_bits1_needed ||
	    (copyreverse == 1 && depth > 0 && rndbits2 < ressut_bits2_needed) ||
	  rndbits3 < ressut_bits3_needed ||
	  rndbits4 < ressut_bits4_needed ||
	  rndbits5 < ressut_bits5_needed ||
	  rndbits6 < ressut_bits6_needed ||
	  rndbits7 < ressut_bits7_needed ||
	  rndbits20 < ressut_bits20_needed ||
	  rndbits21 < ressut_bits21_needed ||
	  rndbits30 < ressut_bits30_needed ||
	  d < RESSU_MIN_ROUNDS ||
	  clockbytes < RESSU_MIN_CLOCKBYTES; d++) {

#define aDEBUG6 2
	
	//
	//  calculate rndbits1
	//
	
	// save previous round

        for(e = 0; e < 1024; e++) {
	  prevperiods[e] = periods[e];
	}

	ressu_genbytes_single_do(ressut_bytes, ressut);

	// find new lim1
	
	lim = lim1;
	f = -1;
	for(e = 0; e < 1024; e++) {
	  if(prevperiods[e] > 0 && prevperiods[e] == lim) {
	    if(f == -1 || (periods[e]>0 && f<periods[e])) {
	      f  = periods[e];
	    }
	  }
	}

	if(f != -1)
	  lim = f;

	lim1a = lim;
	
	// find highest amount of chains
	
	high1 = -1;
	for(e = 0; e < 1024; e++) {
	  if(high1 == -1 || high1 < periods[e]) {
	    high1 = periods[e];
	  }
	}

	// and second highest
	
	high2 = -1;
	for(e = 0; e < 1024; e++) {
	  if( (high2 == -1 && periods[e] < high1) ||
	      (high2 < periods[e] && periods[e] < high1) ) {
	    high2 = periods[e];
	  }
	}

	// and average

	int psum = 0;
	int pcnt = 0;
	for(e = 0; e < 1024; e++) {
	  if(periods[e] > 0) {
	    psum += periods[e];
	    pcnt++;
	  }
	}

	lim1b = (int)((double)psum / pcnt);
	
	// find next smaller than average

	f = -1;
	for(e = 0; e < 1024; e++) {
	  if( (f == -1 && periods[e] < lim1b) ||
	      (f < periods[e] && periods[e] < lim1b) ) {
	    f = periods[e];
	  }
	}

	if(f != -1)
	  lim1b = f;

	if(lim == 0 || lim > lim1b)
	  lim = lim1b;

	// if lim greater that second highest,
	// set to second highest

	if(lim > high2) {
	  lim = high2;
	}
		
	lim1 = lim;

	// find next greater than lim
	
	f = -1;
	for(e = 0; e < 1024; e++) {
	  if(periods[e] > lim &&
	     (f == -1 || periods[e] < f))
	    f = periods[e];
	}
	if(f != -1)
	  lim = f;

	lim2 = lim;

	// calculate rndbits1

#define aDEBUG14A 2
	
	rndbits1 = 0;
	for(e = 0; e < 1024; e++) {
	  if(periods[e] > 0 && periods[e] < lim) {
	    rndbits1 += periods[e];
	  }
	}
	
	//
	//  calculate rndbits3
	//

#define aDEBUG14C 2
	
	rndbits3high = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits3high < periods[e])
	    rndbits3high = periods[e];
	}

	rndbits3 = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits3high > periods[e]) {
	    rndbits3 += periods[e];
	  }
	}

	//
	//  calculate rndbits4
	//

#define aDEBUG14D 2
	
	rndbits4highdigits = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits4highdigits < (int)log10((double)periods[e]) + 1) {
	    rndbits4highdigits = (int)log10((double)periods[e]) + 1;
	  }
	}

	rndbits4 = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits4highdigits > (int)log10((double)periods[e]) + 1) {
	    rndbits4 += periods[e];
	  }
	}

	//
	//  calculate rndbits5
	//

#define aDEBUG14E 2
	
	rndbits5 = 0;

	for(e = 0; e < 1024; e++) {
	  rndbits5 += periods[e];
	}

	//
	//  calculate rndbits6
	//

#define aDEBUG14F 2
	
	rndbits6high = 0;
	rndbits6pos = 0;
	rndbits6 = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits6high < periods[e]) {
	    rndbits6high = periods[e];
	    rndbits6pos = e;
	  }
	}

	for(e = 0; e < 1024; e++) {
	  if(rndbits6high > periods[e] && periods[e] > 0) {
	    if(rndbits6pos > e)
	      rndbits6 += log2((double)rndbits6pos - e) * periods[e];
	    else
	      rndbits6 += log2((double)e - rndbits6pos) * periods[e];
	  }
	}

	//
	//  calculate rndbits7
	//

#define aDEBUG14G 2
	
	rndbits7high = 0;
	rndbits7 = 0;
	for(e = 0; e < 1024; e++) {
	  if(rndbits7high < periods[e])
	    rndbits7high = periods[e];
	}

	for(e = 0; e < 1024; e++) {
	  if(rndbits7high > periods[e] && periods[e] > 0) {
	    rndbits7 += log2((double)rndbits7high - periods[e]) * periods[e];
	  }
	}
	
#define aDEBUG14W 2

#ifdef DEBUG14W

	fprintf(stderr,"rndbits1:%d",rndbits1);
	fprintf(stderr,", 2:%d",rndbits2);
	fprintf(stderr,", 3:%d",rndbits3);
	fprintf(stderr,", 4:%d",rndbits4);
	fprintf(stderr,", 5:%d",rndbits5);
	fprintf(stderr,", 6:%d",rndbits6);
	fprintf(stderr,", 7:%d",rndbits7);
	fprintf(stderr,", 20:%d",rndbits20);
	fprintf(stderr,", 21:%d",rndbits21);
	fprintf(stderr,", 22:%d",rndbits22);
	fprintf(stderr,", 30:%d",rndbits30);
	fprintf(stderr,"\n");

#endif
      } // for(d = 0;
      
      //
      // debug display for rndbits1
      //

#ifdef DEBUG14A
	
      rndbits1 = 0;
      for(e = 0; e < 1024; e++) {
	if(periods[e] > 0 && periods[e] < lim) {
	  rndbits1 += periods[e];
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%ld", periods[e]);
	  fprintf(stderr,", rndbits1+prev:%d", rndbits1);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      //
      //  debug display for rndbits3
      //

#ifdef DEBUG14C
	
      rndbits3 = 0;
      for(e = 0; e < 1024; e++) {
	if(rndbits3high > periods[e] &&
	   periods[e] > 0) {
	  rndbits3 += periods[e];
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%ld", periods[e]);
	  fprintf(stderr,", rndbits3+prev:%d", rndbits3);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      //
      //  debug display for rndbits4
      //

#ifdef DEBUG14D
      
      rndbits4 = 0;
      for(e = 0; e < 1024; e++) {
	if(rndbits4highdigits > (int)log10((double)periods[e]) + 1 &&
	   periods[e] > 0) {
	  rndbits4 += periods[e];
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%ld", periods[e]);
	  fprintf(stderr,", rndbits4+prev:%d", rndbits4);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      //
      //  debug display for rndbits5
      //

#ifdef DEBUG14E

      rndbits5 = 0;

      for(e = 0; e < 1024; e++) {
	if(periods[e] > 0) {
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%ld", periods[e]);
	  rndbits5 += periods[e];
	  fprintf(stderr,", rndbits5+prev:%d", rndbits5);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      //
      //  debug diplay for rndbits6
      //

#ifdef DEBUG14F
	
      rndbits6 = 0;
      for(e = 0; e < 1024; e++) {
	if(rndbits6high > periods[e] &&
	   periods[e] > 0) {
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%lu", periods[e]);

	  double l2;

	  if(rndbits6pos > e) {
	    fprintf(stderr,", pos-e:%d", rndbits6pos - e);
	    l2 = log2((double)rndbits6pos - e);
	  } else {
	    fprintf(stderr,", e-pos:%d", e - rndbits6pos);
	    l2 = log2((double)e - rndbits6pos);
	  }
	  fprintf(stderr,", log2(prev):%f", l2);
	  fprintf(stderr,", periods*prev:%ld", (long int) ((double)periods[e] * l2));
	  rndbits6 += l2 * periods[e];
	  fprintf(stderr,", rndbits6+prev:%d", rndbits6);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      //
      //  debug diplay for rndbits7
      //

#ifdef DEBUG14G

      rndbits7 = 0;
      for(e = 0; e < 1024; e++) {
	if(rndbits7high > periods[e] &&
	   periods[e] > 0) {
	  rndbits7 += log2((double)rndbits7high - periods[e]) * periods[e];
	  fprintf(stderr,"e:%d", e);
	  fprintf(stderr,", periods:%ld", periods[e]);
	  fprintf(stderr,", high-prev:%ld", rndbits7high-periods[e]);
	  double l2=log2((double)rndbits7high-periods[e]);
	  fprintf(stderr,", log2(prev):%f", l2);
	  fprintf(stderr,", periods*prev:%ld", (long int) ((double)periods[e] * l2));
	  fprintf(stderr,", rndbits7+prev:%d", rndbits7);
	  fprintf(stderr,"\n");
	}
      }

#endif
      
      if(stats) {

	if(newressu_output == 1)
	  fprintf(stderr,"\n");
	newressu_output = 0;
	
	//
	//  display statistics
	//
	fprintf(stderr, "rounds:%d", d);
	long chains = 0;
    
	for(e = 0; e < 1024; e++) {
	  if(periods[e] > 0) {
	    fprintf(stderr, " %d:%lu", e, periods[e]);
	    chains += periods[e];
	  }
	}

	fprintf(stderr, ", chains:%ld", chains);
	fprintf(stderr, ", blocks:%ld", cblocks);
	
#ifdef DEBUG_SORTED
	
	fprintf(stderr, ", sorted:");
	int g = 0;
	for(;;) {
	  f = -1;
	  for(e = 0; e < 1024; e++) {
	    if( (f == -1 && periods[e] > g) ||
		(periods[e] > g && f > periods[e]) )
	      f = periods[e];
	  }
	  if(f == -1)
	    break;

	  g = f;
	  fprintf(stderr," %d", g);
	}
	
#endif
	fprintf(stderr, ", ressut size:%d", ressut_bytes);
	fprintf(stderr, ", high1:%d", high1);
	fprintf(stderr, ", high2:%d", high2);
	fprintf(stderr, ", lim1a:%d", lim1a);
	fprintf(stderr, ", lim1b:%d", lim1b);
	fprintf(stderr, ", lim1:%d", lim1);
	fprintf(stderr, ", lim2:%d", lim2);
	fprintf(stderr, ", div:%f", (double)lim2 / lim1);
	fprintf(stderr, ", clockbytes:%ld", clockbytes);
	fprintf(stderr, ", rndbits1:%d", rndbits1);
	fprintf(stderr, ", rndbits2:%d", rndbits2);
	fprintf(stderr, ", rndbits3high:%d", rndbits3high);
	fprintf(stderr, ", rndbits3:%d", rndbits3);
	fprintf(stderr, ", rndbits4highdigits:%d", rndbits4highdigits);
	fprintf(stderr, ", rndbits4:%d", rndbits4);
	fprintf(stderr, ", rndbits5:%d", rndbits5);
	fprintf(stderr, ", rndbits6high:%d", rndbits6high);
	fprintf(stderr, ", rndbits6:%d", rndbits6);
	fprintf(stderr, ", rndbits7high:%d", rndbits7high);
	fprintf(stderr, ", rndbits7:%d", rndbits7);
	fprintf(stderr, ", rndbits20:%d", rndbits20);
	fprintf(stderr, ", rndbits21:%d", rndbits21);
	fprintf(stderr, ", rndbits22:%d", rndbits22);
	fprintf(stderr, ", 20-21:%d", rndbits20 - rndbits21);
	fprintf(stderr, ", 21-22:%d", rndbits21 - rndbits22);
	fprintf(stderr, "\n");
	fflush(stderr);
      } // if(stats
#ifdef DEBUG8
      ressu_dump("ressug", sizeof(ressut), ressut, 32);      
#endif
    } // if(ressut_pos == 0)
    buffer[c] ^= ressut[ressut_pos];
    ressut_pos = (ressut_pos + 1) % ressut_bytes;
#ifdef OLD1
    ressut_f = (ressut_f + ressut[ressut_pos] + 2) % ressut_bytes; // bad for randomness... JariK 2023
    buffer[c] ^= ressut[ressut_f];
    ressut_pos = (ressut_pos + 1) % ressut_bytes;
#endif
    
  } // for(c = 0; c < size; c++)

  if(verbose) {
    fprintf(stdout,"ressu");
    for(c = 0; c < size; c++) {
      if(c > 0 && c % 32 == 0)
	fprintf(stdout," ");
      fprintf(stdout,"%02x", buffer[c]);
      newressu_output = 1;
    }
    fprintf(stdout,"\n");
  }
  
#ifdef DEBUG8

  ressu_dump("ressu", size, buffer, 32);

#endif
  
  genbytes += size;
}

void readfile_xor(int size, unsigned char *buffer, unsigned char *filename)
{
  int c, n, filebuffer_pos = 0;
  unsigned char filebuffer[64];
  FILE *fp1;

  if((fp1 = fopen(filename, "rb")) == NULL) {
    fprintf(stderr,"%s: fopen(): cannot open file %s\n",
	    procname, filename);
    exit(1);
  }

  for(c = 0; c < size; c++) {
    if(filebuffer_pos == 0) {
      n = (size - c < sizeof(filebuffer)) ? size - c : sizeof(filebuffer);
      if(fread(filebuffer, 1, n, fp1) < n) {
	fprintf(stderr,"%s: fread(): cannot read file %s\n",
		procname, filename);
	exit(1);
      }
#ifdef DEBUG8
      ressu_dump("file", n, filebuffer, 32);
#endif
    } // end of if(file_pos == 0
    buffer[c] ^= filebuffer[filebuffer_pos];
    filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);
  } // end of for(c = 0; c < size; c++

  fclose(fp1);

#ifdef DEBUG8
  ressu_dump("return", size, buffer, 32);
#endif
  
  memset(filebuffer, 0, sizeof(filebuffer)); // forget file
}

static unsigned char urandomfilename[128] = "/dev/urandom";

void urandom_bytes(int size, unsigned char *buffer)
{
  readfile_xor(size, buffer, urandomfilename);
#ifdef DEBUG8
  ressu_dump("urandom", size, buffer, 32);
#endif
}

#ifdef USE_RANDOM

static unsigned char randomfilename[128] = "/dev/random";

void random_bytes(int size, unsigned char *buffer)
{
  readfile_xor(size, buffer, randomfilename);
#ifdef DEBUG8
  ressu_dump("random", size, buffer, 32);
#endif
}

#endif

#ifdef SHA256

#define PSEUDORESSU_LIMIT 1048576 // limit between rekeys
#define TOPUP_BYTES 32*1024 // bytes between topups
#define TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define aTOPUP_TWICE 2 // off by default

unsigned long topup_bytes = TOPUP_BYTES;

static unsigned char pseudoressu_key[HashLen]; // 32 bytes, 256 bits

static void pseudoressu_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu_key, sizeof(pseudoressu_key));
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void pseudoressu_addrandomness(int size, unsigned char *buffer)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu_key, sizeof(pseudoressu_key));
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashUpdate(&hash, buffer, size);
  HashFinal(pseudoressu_key, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void pseudoressu_topup()
{
  unsigned char topup[TOPUP_SIZE]; // 32 bytes, 256 bits

  ressu_genbytes(sizeof(topup), topup);

  pseudoressu_addrandomness(sizeof(topup), topup);

  memset(&topup, 0, sizeof(topup)); // forget topup
}

void pseudoressu_bytes(int size, unsigned char *buffer) // JariK 2022
{
  int c;
  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
  static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudoressu_pos == 0) {
      if(topup_counter == 0) {
	if(initneeded) {
	  ressu_genbytes(sizeof(pseudoressu_key), pseudoressu_key); // set first key
#ifdef DEBUG8
	  ressu_dump("first key", sizeof(pseudoressu_key), pseudoressu_key, 32);
#endif
	  initneeded = 0;
	} // end of if(initneeded
	
	pseudoressu_topup(); // add randomness to key, first block also
#ifdef TOPUP_TWICE
	pseudoressu_topup(); // add randomness to key, first block also
#endif
	topup_counter = topup_bytes;
      } // end of if(topup_counter == 0
      
      pseudoressu_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
      ressu_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
      topup_counter -= sizeof(pseudoressu);
    } // end of if(pseudoressu_pos == 0

    buffer[c] ^= pseudoressu[pseudoressu_pos];
    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
  } // end of for(c = 0; c < size; c++
  
  pseudoressu_internalbytes(pseudoressu_key); // replace key with new random one
#ifdef DEBUG8
  ressu_dump("new key", sizeof(pseudoressu_key), pseudoressu_key, 32);
#endif
#ifdef DEBUG8
  ressu_dump("pseudoressu2", size, buffer, 32);
#endif
}

void ressutwist_bytes(int size, unsigned char *buffer) // JariK 2023
{
  //urandom_bytes(size, buffer);
  ressu_genbytes(size, buffer);
  pseudoressu_bytes(size, buffer);
}

#define aDEBUG15 2

static unsigned long long ressu_useconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}

static unsigned char ressu_lowusec() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

static int randomness = 0;

#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )

void ressu_round(int size, unsigned char *buffer) // ressu JariK 2013
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	randomness++;
      }
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + buffer[d] + 2) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
  }
}

static void ressu2_round(int size, unsigned char *buffer) // ressu2 JariK 2013, 2025
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	randomness++;
      }
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + 16 + buffer[d] + 2) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

static void ressu2_1_round(int size, unsigned char *buffer) // ressu2 JariK 2013
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1, index = 0;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = ressu_lowusec();
      buffer[d] = e ^ (byte + index);
      if(prevbyte != byte) {
	prevbyte = byte;
	index = 0;
	randomness++;
      }
      index+=2;
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + buffer[d] + 2 + 16) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

#define aDEBUG16A 2

#define RESSU2_BYTES 2048
#define RESSU2_RANDOMNESS_NEEDED 2048
#define RESSU2_CLOCKS_NEEDED 20480 // now 20480
#define RESSU2_MINIMUM_ROUNDS 5

void ressu2_bytes(int size, unsigned char *buffer) // JariK 2013, 2026
{
  int c, d, clocksused;
  static int ressu_pos = 0;
  static unsigned char ressu[RESSU2_BYTES];

  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      randomness = 0;
      clocksused = 0;
      //memset(&ressu, 0, sizeof(ressu)); // forget buffer
      for(d = 0; d < RESSU2_MINIMUM_ROUNDS ||
	    randomness < RESSU2_RANDOMNESS_NEEDED ||
	    clocksused < RESSU2_CLOCKS_NEEDED
	    ; d++) {
	ressu2_round(sizeof(ressu), ressu);
	clocksused += (sizeof(ressu) * 8);
      }
#ifdef DEBUG8
      ressu_dump("ressu2g", sizeof(ressu), ressu, 32);      
#endif
      if(stats) {
	fprintf(stdout,"rounds:%d", d);
	fprintf(stdout,", randomness:%d", randomness);
	fprintf(stdout,", clocksused:%d", clocksused);
	fprintf(stdout,"\n");
      }
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  ressu_dump("ressu2", size, buffer, 32);
#endif
}

#define PSEUDORESSU2_TOPUP_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define aPSEUDORESSU2_TOPUP_TWICE 2 // off by default

unsigned long pseudoressu2_topup_bytes = PSEUDORESSU2_TOPUP_BYTES;

static unsigned char pseudoressu2_key[HashLen]; // 32 bytes, 256 bits

static void pseudoressu2_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void pseudoressu2_addrandomness(int size, unsigned char *buffer)
{
  unsigned long long usec;
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  usec = ressu_useconds(); // add timestamp to hash
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  usec = clock(); // add processor time to hash (for randomness)
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  HashUpdate(&hash, buffer, size); // add given randomness to hash
  HashFinal(pseudoressu2_key, &hash); // save as new key
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void pseudoressu2_topup()
{
  unsigned char topup[TOPUP_SIZE]; // 32 bytes, 256 bits

  memset(&topup, 0, sizeof(topup)); // forget topup
  ressu2_bytes(sizeof(topup), topup);
#ifdef DEBUG8
  ressu_dump("topup", sizeof(topup), topup, 32);
#endif
  pseudoressu2_addrandomness(sizeof(topup), topup);

  memset(&topup, 0, sizeof(topup)); // forget topup
}

void pseudoressu2_bytes(int size, unsigned char *buffer) // JariK 2022, 2025
{
  int c;
  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
  static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudoressu_pos == 0) {
      if(topup_counter == 0) {
	if(initneeded) {
	  ressu2_bytes(sizeof(pseudoressu2_key), pseudoressu2_key); // get first key
#ifdef DEBUG8
	  ressu_dump("first key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
	  initneeded = 0;
	} // end of if(initneeded
	
	pseudoressu2_topup(); // add randomness to key, first block also
#ifdef PSEUDORESSU2_TOPUP_TWICE
	pseudoressu2_topup(); // add randomness to key, first block also
#endif
	topup_counter = pseudoressu2_topup_bytes;
      } // end of if(topup_counter == 0
      
      pseudoressu2_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
      ressu_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
      topup_counter -= sizeof(pseudoressu);
    } // end of if(pseudoressu_pos == 0

    buffer[c] ^= pseudoressu[pseudoressu_pos];
    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
  } // end of for(c = 0; c < size; c++
  
  pseudoressu2_internalbytes(pseudoressu2_key); // replace key with new random one
#ifdef DEBUG8
  ressu_dump("new key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
#ifdef DEBUG8
  ressu_dump("pseudoressu", size, buffer, 32);
#endif
}

void ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023, 2025
{
  //urandom_bytes(size, buffer);
  ressu2_bytes(size, buffer);
  pseudoressu2_bytes(size, buffer);
}

static void ressu3_round(int size, unsigned char *buffer) // ressu2 JariK 2013
{
  int c, d, byte, length = 0;
  unsigned char e;
  static int f = 0, prevbyte = -1, prevlength = -1;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	if(prevlength != length) {
	  prevlength = length;
	  randomness++;
	}
	length = 0;
      }
      length++;
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + buffer[d] + 2 + 16) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

#define aDEBUG16A 2

#define RESSU3_BYTES 2048
#define RESSU3_RANDOMNESS_NEEDED 2048
#define RESSU3_CLOCKS_NEEDED 20480 // now 20480
#define RESSU3_MINIMUM_ROUNDS 5

void ressu3_bytes(int size, unsigned char *buffer) // JariK 2013
{
  int c, d, clocksused;
  static int ressu_pos = 0;
  static unsigned char ressu[RESSU3_BYTES];

  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      randomness = 0;
      clocksused = 0;
      //memset(&ressu, 0, sizeof(ressu)); // forget buffer
      for(d = 0; d < RESSU3_MINIMUM_ROUNDS ||
	    randomness < RESSU3_RANDOMNESS_NEEDED ||
	    clocksused < RESSU3_CLOCKS_NEEDED
	    ; d++) {
	ressu3_round(sizeof(ressu), ressu);
	clocksused += (sizeof(ressu) * 8);
      }
#ifdef DEBUG8
      ressu_dump("ressu3g", sizeof(ressu), ressu, 32);      
#endif
      if(stats) {
	fprintf(stdout,"rounds:%d", d);
	fprintf(stdout,", randomness:%d", randomness);
	fprintf(stdout,", clocksused:%d", clocksused);
	fprintf(stdout,"\n");
      }
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  ressu_dump("ressu3", size, buffer, 32);
#endif
}

#define SINGLE_BYTES 2048

void single_bytes(int size, unsigned char *buffer) // JariK 2013
{
  int c, clocksused;
  static int ressu_pos = 0;
  static unsigned char ressu[SINGLE_BYTES];

  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      randomness = 0;
      clocksused = 0;
      memset(&ressu, 0, sizeof(ressu)); // forget buffer
      ressu2_round(sizeof(ressu), ressu);
#ifdef DEBUG8
      ressu_dump("singleg", sizeof(ressu), ressu, 32);      
#endif
      if(stats) {
	fprintf(stdout,"rounds:1");
	fprintf(stdout,", randomness:%d", randomness);
	fprintf(stdout,", clocksused:%d", clocksused);
	fprintf(stdout,"\n");
      }
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  ressu_dump("single", size, buffer, 32);
#endif
}

static unsigned long long pseudorandom_useconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
#ifdef DEBUG15
  fprintf(stdout,"usec:%ld(%ld)", tv.tv_usec, (unsigned long)sizeof(tv.tv_usec));
  fprintf(stdout,", sec:%ld(%ld)", tv.tv_sec, (unsigned long)sizeof(tv.tv_sec));
  fprintf(stdout,", total:%ld", tv.tv_usec + 1000000 * tv.tv_sec);
  fprintf(stdout,", total1(ll):%lld", (unsigned long long)tv.tv_usec + 1000000 * tv.tv_sec);
  fprintf(stdout,", total2(ll):%lld", (unsigned long long)tv.tv_usec + 1000000ULL * (unsigned long long)tv.tv_sec);
  fprintf(stdout,", sizeof(ull):%ld", (unsigned long)sizeof(unsigned long long));
  fprintf(stdout,"\n");
#endif
  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}

static unsigned char pseudorandom_key[HashLen]; // 32 bytes, 256 bits

static void pseudorandom_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudorandom_key, sizeof(pseudorandom_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

#define PSEUDORANDOM_RANDOMNESS_NEEDED 256 // now 256, bits in hash
#define PSEUDORANDOM_MINIMUM_ROUNDS 16 // now 16
#define PSEUDORANDOM_BUFFER_SIZE 128 // now 128
#define PSEUDORANDOM_CLOCKS_NEEDED 20480 // now 20480

static void pseudorandom_topup()
{
  int c, clocksused;
  static int initneeded = 1;
  unsigned long long usec;
  static unsigned char buffer[PSEUDORANDOM_BUFFER_SIZE];
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudorandom_key, sizeof(pseudorandom_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();

  if(initneeded) { // clear buffer once in the beginning
    memset(&buffer, 0, sizeof(buffer));
    initneeded = 0;
  }

  clocksused = 0;
  randomness = 0;

  for(c = 0; c < PSEUDORANDOM_MINIMUM_ROUNDS ||
	randomness < PSEUDORANDOM_RANDOMNESS_NEEDED ||
	clocksused < PSEUDORANDOM_CLOCKS_NEEDED
	; c++) {
    usec = pseudorandom_useconds(); // add timestamp to hash
#ifdef DEBUG16A
    if(stats)
      fprintf(stdout,"%02d %llx ", c, usec);
#endif
    HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
    randomness++; // calculate bit for full time

    ressu_round(sizeof(buffer), buffer); // one round, eight bits of ressu
    clocksused += (sizeof(buffer) * 8);

#ifdef DEBUG16A
    if(stats) {
      for(int d = 0; d < sizeof(buffer); d++)
	fprintf(stdout,"%02x", buffer[d]);
      fprintf(stdout,"\n");
      fflush(stdout);
    }
#endif
    HashUpdate(&hash, (unsigned char *)&buffer, sizeof(buffer));
  }
  //HashUpdate(&hash, (unsigned char *)&buffer, sizeof(buffer));

  HashFinal(pseudorandom_key, &hash); // save as new key
#ifdef DEBUG8
  ressu_dump("topup key", sizeof(pseudorandom_key), pseudorandom_key, 32);
#endif

#ifdef DEBUG16A
  if(stats) {
    fprintf(stdout,"randomness:%d", randomness);
    fprintf(stdout,", clocksused:%d\n", clocksused);
  }
#endif
  memset(&hash, 0, sizeof(hash)); // forget hash
}

#define PSEUDORANDOM_TOPUP_BYTES 32*1024 // bytes between topups
#define aPSEUDORANDOM_TOPUP_TWICE 2

void pseudorandom_bytes(int size, unsigned char *buffer) // JariK 2025
{
  int c;
  static int pseudorandom_pos = 0, topup_counter = 0;
  static unsigned char pseudorandom[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudorandom_pos == 0) {
      if(topup_counter == 0) {
	pseudorandom_topup(); // add randomness to key, first block also
#ifdef PSEUDORANDOM_TOPUP_TWICE
	pseudorandom_topup(); // add randomness to key, first block also
#endif
	topup_counter = PSEUDORANDOM_TOPUP_BYTES;
      } // end of if(topup_counter == 0
      pseudorandom_internalbytes(pseudorandom); // get random bits using the key
#ifdef DEBUG8
      ressu_dump("next data", sizeof(pseudorandom), pseudorandom, 32);
#endif
      topup_counter -= sizeof(pseudorandom);
    } // end of if(pseudorandom_pos == 0
    buffer[c] ^= pseudorandom[pseudorandom_pos]; 
    pseudorandom_pos = (pseudorandom_pos + 1) % sizeof(pseudorandom);
  } // end of for(c = 0; c < size; c++
  pseudorandom_internalbytes(pseudorandom_key); // replace key with new random one
#ifdef DEBUG8
  ressu_dump("new key", sizeof(pseudorandom_key), pseudorandom_key, 32);
#endif
#ifdef DEBUG8
  ressu_dump("pseudorandom", size, buffer, 32);
#endif
}

#endif // end of #ifdef SHA256

#ifdef SHA256

void dumpbin(FILE *fp1, int len, unsigned char *buf)
{
  int c;

  for(c = 0; c < len; c++)
    if(isprint(buf[c]) && buf[c] != ' ')
      fputc(buf[c], stderr);
    else
      fprintf(stderr,"\\%02x", buf[c]);
}

void dumpline(FILE *fp1, int len, unsigned char *buf)
{
  int c;

  for(c = 0; c < len; c++)
    fprintf(fp1,"%02x", buf[c]);
}

static unsigned char stream_key[HashLen]; // 32 bytes, 256 bits

static void stream_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, stream_key, sizeof(stream_key));
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);

  memset(&hash, 0, sizeof(hash)); // forget hash
}

static int stream_pos = 0;
static unsigned long stream_input_bytes = 0;

#define STREAM_REKEY 2048 // rekey blocksize now 2048

void stream_bytes(int size, unsigned char *buffer) // JariK 2023
{
  int c;
  static unsigned char stream[HashLen]; // 32 bytes, 256 bits
  
  for(c = 0; c < size; c++) {

    if(stream_pos == 0) {

      if(stream_input_bytes % STREAM_REKEY == 0) {
	stream_internalbytes(stream_key); // change key, first block also
#ifdef DEBUG8
	ressu_dump("rekey", sizeof(stream_key), stream_key, 32);
#endif
      }

      stream_internalbytes(stream); // read next "random" bytes
#ifdef DEBUG8
      ressu_dump("nextdata", sizeof(stream), stream, 32);
#endif
      
      stream_input_bytes += sizeof(stream);
    } // end of if(stream_pos == 0

    buffer[c] = stream[stream_pos];
    stream_pos = (stream_pos + 1) % sizeof(stream);
  } // end of for(c = 0; c < size; c++

#ifdef DEBUG8
  ressu_dump("stream", size, buffer, 32);
#endif
  
}

#define STREAM_KEY_ROUNDS 4096 // should be fast enough and slow enough, now 4096

void stream_open(int size, unsigned char *key) // size = 0 --> zero terminated string
{
  int c;
  HashCtx hash;

  clearcvar();
  stream_pos = 0;
  stream_input_bytes = 0;

  if(size == 0)
    size = strlen(key);
  
  HashInit(&hash);
  HashUpdate(&hash, key, size);
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();

  for(c = 0; c < STREAM_KEY_ROUNDS; c++) {
    HashFinal(stream_key, &hash);

    HashInit(&hash);
    HashUpdate(&hash, stream_key, sizeof(stream_key));
    HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
    inccvar();
  }

  HashFinal(stream_key, &hash);

#define DEBUG21 2

#ifdef DEBUG21
  fflush(stdout);
  fprintf(stderr,"%s: stream_open():", procname);
  fprintf(stderr," randomness from key, key=");
  dumpbin(stderr, size, key);
  fprintf(stderr,"\n");
  fflush(stderr);
#endif

#ifdef DEBUG8
  ressu_dump("first key", sizeof(stream_key), stream_key, 32);
#endif

  memset(&hash, 0, sizeof(hash)); // forget hash
}

#endif // end of #ifdef SHA256

void test_bytes(int size, unsigned char *buffer) // JariK 2023
{
  // insert your generator here, run it with
  // --test command line parameter (source for
  // randomness)

  urandom_bytes(size, buffer);
  ressutwist_bytes(size, buffer);
  ressu2twist_bytes(size, buffer);
  
  //memset(buffer, 0, size);

  //for(int c = 0; c < size; c++)
  //  buffer[c] = c & 0xff;
}

void newressu_version()
{
  fprintf(stderr, "%s", programname); // touch these outside #ifdef MAIN
  fprintf(stderr, ", %s", copyright);
}

#ifdef MAIN

#include <unistd.h>
#include <ctype.h>
#include <malloc.h>

#include "newressu.h"

#define SAMPLE_WRITE 2 // on by default
#define SAMPLE_HASH 2 // on by default (for now)
#define SAMPLE_SYNC 2 // on by default (for now (exfat))
#define USE_TIMER 2
#define aUSE_DUMMY 2

void command_readline(unsigned char *command, int linelen, unsigned char *line)
{
  FILE *fp1;

  line[0] = '\0';
  
  if((fp1 = popen(command, "r")) == NULL) {
    fprintf(stdout,"%s: popen(): cannot open process '%s'\n",
	    procname, command);
  } else  {
    fgets(line, linelen, fp1);
    if(line[strlen(line)-1] == '\n')
      line[strlen(line)-1] = '\0';
  }
}

long long command_countlines(unsigned char *command)
{
  unsigned char buffer[1024];
  long long ll = 0;
  FILE *fp1;

  if((fp1 = popen(command, "r")) == NULL) {
    fprintf(stdout,"%s: popen(): cannot open process '%s'\n",
	    procname, command);
  } else  {
    while(fgets(buffer, sizeof(buffer), fp1) != NULL)
      ll++;
  }
  return(ll);
}

#define aDEBUG25 // off by default
#define aDEBUG19 // off by default

#ifdef DEBUG19

void save_path(int path_length, unsigned char *path)
{
  if((getcwd(path, path_length)) == NULL) {
    fprintf(stdout,"%s: save_path(): cannot get working directory (getcwd())\n",
	    procname);
  }
#ifdef DEBUG25
  fprintf(stderr,"%s: save_path(): saved current path (getcwd()), path = %s\n",
	  procname, path);
#endif
}

int exists_path(unsigned char *path)
{
  FILE *fp1;
  
  if((fp1 = fopen(path, "r")) != NULL) {
    fclose(fp1);
    //fprintf(stderr,"path %s ok\n", path);
    return(1);
  } else
    return(0);
}

void set_path(unsigned char *path)
{
  if(chdir(path) != 0) {
    fprintf(stdout,"%s: set_path(): cannot change directory (chdir())\n",
	    procname);
  }
#ifdef DEBUG25
  fprintf(stderr,"%s: set_path(): set path (chdir()), path = %s\n",
	  procname, path);
#endif
}

#endif // end of #ifdef DEBUG19

unsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)
{
  int nlen = strlen(needle);;
  unsigned char *p = haystack;

  while(*p != '\0') {
    if(!strncmp(p, needle, nlen) &&
       ( isblank(*(p + nlen)) || ispunct(*(p + nlen)) || *(p + nlen) == '\0' ) && // character after string
       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) // character before string
      return(p);
    p++;
  }
  return(NULL);
}

#ifdef OLD1

unsigned char *newressu_strstr(unsigned char *haystack, unsigned char *needle)
{
  int fl;
  unsigned char *p = haystack;

  while(*p != '\0') {
    fl = strlen(needle);
    if(!strncmp(p, needle, strlen(needle)) &&
       ( isblank(*(p + fl)) || ispunct(*(p + fl)) || *(p + fl) == '\0' ) && // character after string
       ( (p == haystack) || isblank(*(p - 1)) || ispunct(*(p - 1)) ) ) { // character before string
      return(p);
    }
    p++;
  }
  return(NULL);
}

#endif

/*
 *  code for flags functions
 */
/*
🇦
🇧
🇨
🇩
🇪
🇫
🇬
🇭
🇮
🇯
🇰
🇱
🇲
🇳
🇴
🇵
🇶
🇷
🇸
🇹
🇺
🇻
🇼
🇽
🇾
🇿
*/
/*
  🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿
*/

struct idflags { // 202307 JariK
  unsigned char *id;
  unsigned char *flags;
} idsflags[] = {
  { "🇫🇮", "🇫🇮: fi, fin, Finland, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, FINLAND" },
  { "🇦🇽", "🇦🇽: ax, ala, Åland, aland, NORDIC, FINLAND" },
  { "🇸🇪", "🇸🇪: se, swe, Sweden, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇳🇴", "🇳🇴: no, nor, Norway, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇩🇰", "🇩🇰: dk, dnk, Denmark, EU, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC, DENMARK" },
  { "🇫🇴", "🇫🇴: fo, fro, FaroeIslands, NORDIC, DENMARK" },
  { "🇮🇸", "🇮🇸: is, isl, Iceland, NORTHERNEUROPE, EUROPE, EURASIA, NORDIC" },
  { "🇬🇱", "🇬🇱: gl, grl, Greenland, NORTHAMERICA, NORDIC, DENMARK" },
  
  { "🇪🇪", "🇪🇪: ee, est, Estonia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇻", "🇱🇻: lv, lva, Latvia, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  { "🇱🇹", "🇱🇹: lt, ltu, Lithuania, EU, NORTHERNEUROPE, EUROPE, EURASIA, BALTIC" },
  
  { "🇺🇦", "🇺🇦: ua, ukr, Ukraine, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇱", "🇦🇱: al, alb, Albania, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇩", "🇦🇩: ad, and, Andorra, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇲", "🇦🇲: am, arm, Armenia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇦🇹", "🇦🇹: at, aut, Austria, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇦🇿", "🇦🇿: az, aze, Azerbaijan, EASTERNEUROPE, EUROPE, WESTASIA, ASIA, EURASIA" },
  { "🇧🇾", "🇧🇾: by, blr, Belarus, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇪", "🇧🇪: be, bel, Belgium, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇧🇦", "🇧🇦: ba, bih, BosniaandHerzegovina, EASTERNEUROPE, EUROPE" }, // Bosnia and Herzegovina
  { "🇧🇬", "🇧🇬: bg, bgr, Bulgaria, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇷", "🇭🇷: hr, hrv, Croatia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇾", "🇨🇾: cy, cyp, Cyprus, EU, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇨🇿", "🇨🇿: cz, cze, CzechRepublic, EU, EASTERNEUROPE, EUROPE, EURASIA" },  // Czech Republic Czechia
  { "🇫🇷", "🇫🇷: fr, fra, France, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇪", "🇬🇪: ge, geo, Georgia, EASTERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  { "🇩🇪", "🇩🇪: de, deu, Germany, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇬🇷", "🇬🇷: gr, grc, Greece, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇭🇺", "🇭🇺: hu, hun, Hungary, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: ie, irl, Ireland, UK, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇹", "🇮🇹: it, ita, Italy, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇻🇦", "🇻🇦: va, vat, Vatican, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇰🇿", "🇰🇿: kz, kaz, Kazakhstan, EUROPE, EURASIA, CENTRALASIA, ASIA" },
  { "🇱🇮", "🇱🇮: li, lie, Liechtenstein, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇱🇺", "🇱🇺: lu, lux, Luxembourg, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇹", "🇲🇹: mt, mlt, Malta, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇩", "🇲🇩: md, mda, Moldova, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇪", "🇲🇪: me, mne, Montenegro, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇨", "🇲🇨: mc, mco, Monaco, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇪", "🇲🇪: me, mne, Montenegro, EUROPE, EURASIA" },
  { "🇳🇱", "🇳🇱: nl, nld, Netherlands, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇲🇰", "🇲🇰: mk, mkd, Northmacedonia, EASTERNEUROPE, EUROPE, EURASIA" }, // North Macedonia
  { "🇵🇱", "🇵🇱: pl, pol, Poland, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇵🇹", "🇵🇹: pt, prt, Portugal, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇴", "🇷🇴: ro, rou, Romania, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇷🇺", "🇷🇺: ru, rus, Russia, EASTERNEUROPE, EUROPE, EURASIA, NORTHASIA, ASIA, BRICS" },
  { "🇸🇲", "🇸🇲: sm, smr, SanMarino, SOUTHERNEUROPE, EUROPE, EURASIA" }, // San Marino
  { "🇷🇸", "🇷🇸: rs, srb, Serbia, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇰", "🇸🇰: sk, svk, Slovakia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇸🇮", "🇸🇮: si, svn, Slovenia, EU, EASTERNEUROPE, EUROPE, EURASIA" },
  { "🇪🇸", "🇪🇸: es, esp, Spain, EU, SOUTHERNEUROPE, EUROPE, EURASIA" },
  { "🇨🇭", "🇨🇭: ch, che, Switzerland, EU, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇹🇷", "🇹🇷: tr, tur, Turkey, SOUTHERNEUROPE, EUROPE, EURASIA, WESTASIA, ASIA" },
  
  { "🇬🇧", "🇬🇧: gb, gbr, UnitedKingdom, UK, WESTERNEUROPE, EUROPE, EURASIA" },
  { "🇮🇪", "🇮🇪: gb, gbr, England, UK" },
  { "🇮🇪", "🇮🇪: gb, gbr, Scotland, UK" },
  { "🇮🇪", "🇮🇪: gb, gbr, Wales, UK" },

  { "🇬🇮", "🇬🇮: gi, gib, Gibraltar, UK" },

  { "🇸🇯", "🇸🇯: sj, sjm, JanMayen, NORWAY" }, // Jan Mayen
  
  { "🇦🇮", "🇦🇮: ai, aia, Anguilla, NORTHAMERICA, UK" },
  { "🇦🇬", "🇦🇬: ag, atg, AntiguaAndBarbuda, NORTHAMERICA" }, // Antigua and Barbuda 
  { "🇦🇼", "🇦🇼: aw, sbw, Aruba, NORTHAMERICA" }, 
  { "🇧🇸", "🇧🇸: bs, bhs, Bahamas, NORTHAMERICA" },
  { "🇧🇧", "🇧🇧: bb, brb, Barbados, NORTHAMERICA" },
  { "🇧🇿", "🇧🇿: bz, blz, Belize, NORTHAMERICA" },
  { "🇧🇲", "🇧🇲: bm, bmu, Bermuda, UK, NORTHAMERICA" },
  { "🇧🇶", "🇧🇶: bq, bes, Bonaire, NETHERLANDS, NORTHAMERICA" },
  { "🇻🇬", "🇻🇬: vg, vgb, BritishVirginIslands, UK, NORTHAMERICA" }, // British Virgin Islands
  { "🇨🇦", "🇨🇦: ca, can, Canada, NORTHAMERICA" },
  { "🇰🇾", "🇰🇾: ky, cym, CaymanIslands, UK, NORTHAMERICA" },
  { "🇫🇷", "🇫🇷: fr, fra, ClippertonIsland, FRANCE, NORTHAMERICA" },
  { "🇨🇷", "🇨🇷: cr, cri, CostaRica, NORTHAMERICA" },
  { "🇨🇺", "🇨🇺: cu, cub, Cuba, NORTHAMERICA" },
  { "🇨🇼", "🇨🇼: cw, cuw, Curaçao, curacao, NORTHAMERICA" },
  { "🇩🇲", "🇩🇲: dm, dma, Dominica, NORTHAMERICA" },
  { "🇩🇴", "🇩🇴: do, dom, DominicanRepublic, NORTHAMERICA" }, // Dominican Republic
  { "🇸🇻", "🇸🇻: sv, slv, ElSalvador, NORTHAMERICA" },
  { "🇬🇱", "🇬🇱: gl, grl, Greenland, DENMARK, NORTHAMERICA" },
  { "🇬🇩", "🇬🇩: gd, grd, Grenada, NORTHAMERICA" },
  { "🇬🇵", "🇬🇵: gp, glp, Guadeloupe, FRANCE, NORTHAMERICA" },
  { "🇬🇹", "🇬🇹: gt, gtm, Guatemala, NORTHAMERICA" },
  { "🇭🇹", "🇭🇹: ht, hti, Haiti, NORTHAMERICA" },
  { "🇭🇳", "🇭🇳: hn, hnd, Honduras, NORTHAMERICA" },
  { "🇯🇲", "🇯🇲: jm, jam, Jamaica, NORTHAMERICA" },
  { "🇲🇶", "🇲🇶: mq, mtq, Martinique, FRANCE, NORTHAMERICA" },
  { "🇲🇽", "🇲🇽: mx, mex, Mexico, NORTHAMERICA" },
  { "🇲🇸", "🇲🇸: ms, msr, Montserrat, UK, NORTHAMERICA" },
  { "🇳🇮", "🇳🇮: ni, nic, Nicaragua, NORTHAMERICA" },
  { "🇵🇦", "🇵🇦: pa, pan, Panama, NORTHAMERICA" },
  { "🇵🇷", "🇵🇷: pr, pri, PuertoRico, NORTHAMERICA" },
  { "🇧🇶", "🇧🇶: bq, bes, Saba, NORTHAMERICA" },
  { "🇧🇱", "🇧🇱: bl, blm, SaintBarthélemy, saintbarthelemy, NORTHAMERICA" }, // Saint Barthélemy
  { "🇰🇳", "🇰🇳: kn, kna, SaintKitts, NORTHAMERICA" }, // Saint Kitts and Nevis
  { "🇱🇨", "🇱🇨: lc, lca, SaintLucia, NORTHAMERICA" }, // Saint Lucia
  { "🇲🇫", "🇲🇫: mf, maf, SaintMartin, NORTHAMERICA" }, // Collectivity of Saint Martin
  { "🇸🇽", "🇸🇽: sx, sxm, SintMaarten, NORTHAMERICA" }, // Sint Maarten
  { "🇹🇹", "🇹🇹: tt, tto, TrinidadandTobago, NORTHAMERICA" }, // Trinidad and Tobago
  { "🇹🇨", "🇹🇨: tc, tca, TurksandCaicos, UK, NORTHAMERICA" }, // Turks and Caicos Islands
  { "🇵🇲", "🇵🇲: pm, spm, SaintPierre, NORTHAMERICA" }, // Saint Pierre and Miquelon
  { "🇻🇨", "🇻🇨: vc, vct, SaintVincent, NORTHAMERICA" }, // Saint Vincent and the Grenadines
  { "🇺🇸", "🇺🇸: us, usa, UnitedStatesofAmerica, USA, NORTHAMERICA" }, // United States of America
  { "🇻🇮", "🇻🇮: vi, vir, VirginIslands, USA, NORTHAMERICA" }, // United States Virgin Islands

  { "🇧🇻", "🇧🇻: bv, bvt, BouvetIsland" }, // Bouvet Island
  { "🇺🇲", "🇺🇲: um, umi, Navassa" },
  { "🇸🇭", "🇸🇭: sh, shn, SaintHelena" }, // Saint Helena
  
  { "🇦🇷", "🇦🇷: ar, arg, Argentina, SOUTHAMERICA" },
  { "🇧🇴", "🇧🇴: bo, bol, Bolivia, SOUTHAMERICA" },
  { "🇧🇷", "🇧🇷: br, bra, Brazil, SOUTHAMERICA, BRICS" },
  { "🇨🇱", "🇨🇱: cl, chl, Chile, SOUTHAMERICA" },
  { "🇨🇴", "🇨🇴: co, col, Colombia, SOUTHAMERICA" },
  { "🇪🇨", "🇪🇨: ec, ecu, Ecuador, SOUTHAMERICA" },
  { "🇫🇰", "🇫🇰: fk, flk, FalklandIslands, UK, SOUTHAMERICA" }, // Falkland Islands
  { "🇬🇫", "🇬🇫: gf, guf, FrenchGuiana, SOUTHAMERICA, FRANCE" }, // French Guiana
  { "🇬🇾", "🇬🇾: gy, guy, Guyana, SOUTHAMERICA" },
  { "🇵🇾", "🇵🇾: py, pry, Paraguay, SOUTHAMERICA" },
  { "🇵🇪", "🇵🇪: pe, per, Peru, SOUTHAMERICA" },
  { "🇬🇸", "🇬🇸: gs, sgs, SouthGeorgia, SOUTHAMERICA" }, // South Georgia and the South Sandwich Islands
  { "🇸🇷", "🇸🇷: sr, sur, Suriname, SOUTHAMERICA" },
  { "🇺🇾", "🇺🇾: uy, ury, Uruguay, SOUTHAMERICA" },
  { "🇻🇪", "🇻🇪: ve, ven, Venezuela, SOUTHAMERICA" },

  { "🇦🇪", "🇦🇪: ae, are, UnitedArabEmirates, WESTASIA, ASIA, EURASIA" }, // United Arab Emirates
  { "🇦🇫", "🇦🇫: af, afg, Afghanistan, SOUTHASIA, ASIA, EURASIA" },
  { "🇧🇩", "🇧🇩: bd, bgd, Bangladesh, SOUTHASIA, ASIA, EURASIA" },
  { "🇧🇭", "🇧🇭: bh, bhr, Bahrain, EASTASIA, ASIA, EURASIA" },
  { "🇧🇳", "🇧🇳: bn, brn, Brunei, ASIA, EURASIA" },
  { "🇧🇹", "🇧🇹: bt, btn, Bhutan, SOUTHASIA, ASIA, EURASIA" },
  { "🇨🇳", "🇨🇳: cn, chn, China, EASTASIA, ASIA, EURASIA, BRICS" },
  { "🇭🇰", "🇭🇰: hk, hkg, HongKong, EASTASIA, ASIA, EURASIA" },
  { "🇮🇩", "🇮🇩: id, idn, Indonesia, ASIA, EURASIA" },
  { "🇮🇱", "🇮🇱: il, isr, Israel, WESTASIA, ASIA, EURASIA" },
  { "🇮🇳", "🇮🇳: in, ind, India, SOUTHASIA, ASIA, EURASIA, BRICS" },
  { "🇮🇶", "🇮🇶: iq, irq, Iraq, WESTASIA, ASIA, EURASIA" },
  { "🇮🇷", "🇮🇷: ir, irn, Iran, WESTASIA, ASIA, EURASIA" },
  { "🇯🇴", "🇯🇴: jo, jor, Jordan, WESTASIA, ASIA, EURASIA" },
  { "🇯🇵", "🇯🇵: jp, jpn, Japan, EASTASIA, ASIA, EURASIA" },
  { "🇰🇬", "🇰🇬: kg, kgz, Kyrgyzstan, CENTRALASIA, ASIA, EURASIA" },
  { "🇰🇭", "🇰🇭: kh, khm, Cambodia, ASIA, EURASIA" },
  { "🇰🇷", "🇰🇷: kr, kor, SouthKorea, EASTASIA, ASIA, EURASIA" },
  { "🇰🇼", "🇰🇼: kw, kwt, Kuwait, WESTASIA, ASIA, EURASIA" },
  { "🇱🇦", "🇱🇦: la, lao, Laos, ASIA, EURASIA" },
  { "🇱🇧", "🇱🇧: lb, lbn, Lebanon, WESTASIA, ASIA, EURASIA" },
  { "🇱🇰", "🇱🇰: lk, lka, SriLanka, SOUTHASIA, ASIA, EURASIA" },
  { "🇲🇳", "🇲🇳: mn, mng, Mongolia, EASTASIA, ASIA, EURASIA" },
  { "🇲🇴", "🇲🇴: mo, mac, Macao, EASTASIA, ASIA, EURASIA" },
  { "🇲🇻", "🇲🇻: mv, mdv, Maldives, SOUTHASIA, ASIA, EURASIA" },
  { "🇲🇲", "🇲🇲: mm, mmr, Myanmar, ASIA, EURASIA" },
  { "🇲🇾", "🇲🇾: my, mys, Malaysia, ASIA, EURASIA" },
  { "🇰🇵", "🇰🇵: kp, prk, NorthKorea, EASTASIA, ASIA, EURASIA" },
  { "🇳🇵", "🇳🇵: np, npl, Nepal, SOUTHASIA, ASIA, EURASIA" },
  { "🇴🇲", "🇴🇲: om, omn, Oman, WESTASIA, ASIA, EURASIA" },
  { "🇵🇭", "🇵🇭: ph, phl, Philippines, ASIA, EURASIA" },
  { "🇵🇰", "🇵🇰: pk, pak, Pakistan, SOUTHASIA, ASIA, EURASIA" },
  { "🇵🇸", "🇵🇸: ps, pse, Palestine, WESTASIA, ASIA, EURASIA" },
  { "🇶🇦", "🇶🇦: qa, qat, Qatar, WESTASIA, ASIA, EURASIA" },
  { "🇸🇦", "🇸🇦: sa, sau, SaudiArabia, WESTASIA, ASIA, EURASIA" },
  { "🇸🇬", "🇸🇬: sg, sgb, Singapore, ASIA, EURASIA" },
  { "🇸🇾", "🇸🇾: sy, syr, Syria, WESTASIA, ASIA, EURASIA" },
  { "🇹🇭", "🇹🇭: th, tha, Thailand, ASIA, EURASIA" },
  { "🇹🇯", "🇹🇯: tj, tjk, Tajikistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇹🇱", "🇹🇱: tl, tls, EastTimor, ASIA, EURASIA" },
  { "🇹🇲", "🇹🇲: tm, tkm, Turkmenistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇹🇼", "🇹🇼: tw, twn, Taiwan, EASTASIA, ASIA, EURASIA" },
  { "🇺🇿", "🇺🇿: uz, uzb, Uzbekistan, CENTRALASIA, ASIA, EURASIA" },
  { "🇻🇳", "🇻🇳: vn, vnm, Vietnam, ASIA, EURASIA" },
  { "🇾🇪", "🇾🇪: ye, yem, Yemen, WESTASIA, ASIA, EURASIA" },

  { "🇳🇪", "🇳🇪: ne, ner, Nigeria, AFRICA, WESTAFRICA" },
  { "🇪🇹", "🇪🇹: et, eth, Ethiopia, AFRICA, AFRICA, EASTAFRICA" },
  { "🇪🇷", "🇪🇷: er, eri, Eritrea, AFRICA, EASTAFRICA" },
  { "🇨🇬", "🇨🇬: cg, cog, Congo, AFRICA, CENTRALAFRICA" }, // Rebublic of the Congo
  { "🇨🇩", "🇨🇩: cd, cod, DemocraticCongo, AFRICA, CENTRALAFRICA" }, // Democratic Rebublic of the Congo
  { "🇹🇿", "🇹🇿: tz, tza, Tanzania, AFRICA, EASTAFRICA" },
  { "🇿🇦", "🇿🇦: za, zaf, SouthAfrica, AFRICA, SOUTHAFRICA, BRICS" },
  { "🇰🇪", "🇰🇪: ke, ken, Kenya, AFRICA, EASTAFRICA" },
  { "🇺🇬", "🇺🇬: ug, uga, Uganda, AFRICA, EASTAFRICA" },
  { "🇸🇸", "🇸🇸: ss, ssd, SouthSudan, AFRICA, EASTAFRICA" },
  { "🇸🇩", "🇸🇩: sd, sdn, Sudan, AFRICA, EASTAFRICA" },
  { "🇩🇿", "🇩🇿: dz, dza, Algeria, AFRICA, NORTHAFRICA" },
  { "🇪🇬", "🇪🇬: eg, egy, Egypt, AFRICA, NORTHAFRICA, WESTASIA, ASIA, EURASIA" },
  { "🇱🇾", "🇱🇾: ly, lby, Libya, AFRICA, NORTHAFRICA" },
  { "🇱🇾", "🇱🇾: ly, lby, Madeira, AFRICA, NORTHAFRICA" },
  { "🇲🇦", "🇲🇦: ma, mar, Morocco, AFRICA, NORTHAFRICA" },
  { "🇦🇴", "🇦🇴: ao, ago, Angola, AFRICA, CENTRALAFRICA" },
  { "🇬🇭", "🇬🇭: gh, gha, Ghana, AFRICA, WESTAFRICA" },
  { "🇲🇿", "🇲🇿: mz, moz, Mozambique, AFRICA" },
  { "🇲🇬", "🇲🇬: mg, mdg, Madagascar, AFRICA, EASTAFRICA" },
  { "🇾🇹", "🇾🇹: yt, myt, Mayotte, FRANCE, AFRICA, EASTAFRICA" },
  { "🇨🇮", "🇨🇮: ci, civ, IvoryCoast, AFRICA, WESTAFRICA" },
  { "🇨🇲", "🇨🇲: cm, cmr, Cameroon, AFRICA, CENTRALAFRICA" },
  { "🇳🇪", "🇳🇪: ne, ner, Niger, AFRICA, WESTAFRICA" },
  { "🇧🇫", "🇧🇫: bf, bfa, BurkinaFaso, AFRICA, WESTAFRICA" }, // Burkina Faso
  { "🇲🇱", "🇲🇱: ml, mli, Mali, AFRICA, WESTAFRICA" },
  { "🇲🇼", "🇲🇼: mw, mwi, Malawi, AFRICA, EASTAFRICA" },
  { "🇿🇲", "🇿🇲: zm, zmb, Zambia, AFRICA, EASTAFRICA" },
  { "🇹🇩", "🇹🇩: td, tcd, Chad, AFRICA, CENTRALAFRICA" },
  { "🇸🇴", "🇸🇴: so, som, Somalia, AFRICA, EASTAFRICA" },
  { "🇸🇳", "🇸🇳: sn, sen, Senegal, AFRICA, WESTAFRICA" },
  { "🇿🇼", "🇿🇼: zw, zwe, Zimbabwe, AFRICA, EASTAFRICA" },
  { "🇬🇳", "🇬🇳: gn, gin, Guinea, AFRICA, WESTAFRICA" },
  { "🇷🇪", "🇷🇪: re, reu, Réunion, reunion, FRANCE, AFRICA, EASTAFRICA" }, // Réunion
  { "🇷🇼", "🇷🇼: rw, rwa, Rwanda, AFRICA, EASTAFRICA" },
  { "🇧🇯", "🇧🇯: bj, ben, Benin, AFRICA, WESTAFRICA" },
  { "🇧🇮", "🇧🇮: bi, bdi, Burundi, AFRICA, EASTAFRICA" },
  { "🇹🇳", "🇹🇳: tn, tun, Tunisia, AFRICA, NORTHAFRICA" },
  { "🇹🇬", "🇹🇬: tg, tgo, Togo, AFRICA, WESTAFRICA" },
  { "🇸🇱", "🇸🇱: sl, sle, SierraLeone, AFRICA, WESTAFRICA" }, // Sierra Leone
  { "🇨🇩", "🇨🇩: cd, cod, Congo, AFRICA, CENTRALAFRICA" },
  { "🇨🇫", "🇨🇫: cf, caf, CentralAfrican, CENTRALAFRICA" }, // Central African Republic
  { "🇱🇷", "🇱🇷: lr, lbr, Liberia, AFRICA, WESTAFRICA" },
  { "🇲🇷", "🇲🇷: mr, mrt, Mauritania, AFRICA, WESTAFRICA" },
  { "🇪🇷", "🇪🇷: er, eri, Eritrea, AFRICA, EASTAFRICA" },
  { "🇬🇲", "🇬🇲: gm, gmb, Gambia, AFRICA, WESTAFRICA" },
  { "🇧🇼", "🇧🇼: bw, bwa, Botswana, AFRICA, SOUTHAFRICA" },
  { "🇳🇦", "🇳🇦: na, nam, Namibia, AFRICA, SOUTHAFRICA" },
  { "🇬🇦", "🇬🇦: ga, gab, Gabon, AFRICA, CENTRALAFRICA" },
  { "🇱🇸", "🇱🇸: ls, lso, Lesotho, AFRICA, SOUTHAFRICA" },
  { "🇬🇼", "🇬🇼: gw, gnb, GuineaBissau, AFRICA, WESTAFRICA" }, // Guinea-Bissau
  { "🇬🇶", "🇬🇶: gq, gnq, EquatorialGuinea, CENTRALAFRICA" }, // Equatorial Guinea
  { "🇲🇺", "🇲🇺: mu, mus, Mauritius, AFRICA, EASTAFRICA" },
  { "🇲🇺", "🇲🇺: mz, moz, Mozambique, AFRICA, EASTAFRICA" },
  { "🇸🇿", "🇸🇿: sz, swz, Eswatini, AFRICA, SOUTHAFRICA" },
  { "🇩🇯", "🇩🇯: dj, dji, Djibouti, AFRICA, EASTAFRICA" },
  { "🇰🇲", "🇰🇲: km, com, Comoros, AFRICA" },
  { "🇨🇻", "🇨🇻: cv, cpv, CapeVerde, AFRICA, WESTAFRICA" },
  { "🇪🇭", "🇪🇭: eh, esh, WesternSahara, SPAIN, AFRICA, NORTHAFRICA" }, // Western Sahara
  { "🇸🇹", "🇸🇹: st, stp, SãoToméandPríncipe, saotomeandprincipe, CENTRALAFRICA" }, // São Tomé and Príncipe
  { "🇸🇨", "🇸🇨: sc, syc, Seychelles, AFRICA, EASTAFRICA" },

  { "🇸🇭", "🇸🇭: sh, shn, TristandaCunha, UK" }, // Tristan da Cunha
  
  { "🇦🇺", "🇦🇺: au, aus, Australia, AUSTRALASIA, OCEANIA" },
  { "🇨🇽", "🇨🇽: cx, cxr, Christmasisland, AUSTRALIA" }, // Christmas Island

  { "🇨🇨", "🇨🇨: cc, cck, CocosIslands, AUSTRALIA" }, // Cocos (Keeling) Islands
  
  { "🇮🇲", "🇮🇲: im, imn, ManIsle, UK" }, // Isle of Man
  
  { "🇰🇮", "🇰🇮: ki, kir, Kiribati, MICRONESIA, OCEANIA" },
  { "🇳🇷", "🇳🇷: nr, nru, Nauru, MICRONESIA, OCEANIA" },
  { "🇳🇨", "🇳🇨: nc, ncl, NewCaledonia, FRANCE, OCEANIA" }, // New Caledonia
  { "🇫🇯", "🇫🇯: fj, fji, Fiji, MELANESIA, OCEANIA" },
  { "🇫🇲", "🇫🇲: fm, fsm, Micronesia, MICRONESIA, OCEANIA" },
  { "🇵🇬", "🇵🇬: pg, png, PapuanewGuinea, MELANESIA, OCEANIA" }, // Papua New Guinea
  { "🇻🇺", "🇻🇺: vu, vut, Vanuatu, MELANESIA, OCEANIA" },
  { "🇸🇧", "🇸🇧: sb, slb, SolomonIslands, MELANESIA, OCEANIA" }, // Solomon Islands
  { "🇬🇺", "🇬🇺: gu, gum, Guam, USA, MICRONESIA, OCEANIA" },
  { "🇲🇭", "🇲🇭: mh, mhl, MarshallIslands, MICRONESIA, OCEANIA" }, // Marshall Islands
  { "🇲🇵", "🇲🇵: mp, mnp, NorthernMariana, MICRONESIA, OCEANIA" }, // Northern Mariana Islands
  { "🇵🇫", "🇵🇫: pf, pyf, FrenchPolynesia, FRANCE, POLYNESIA, OCEANIA" }, // French Polynesia
  { "🇼🇸", "🇼🇸: ws, wsm, Samoa, POLYNESIA, OCEANIA" },
  { "🇼🇫", "🇼🇫: wf, wlf, WallisandFutuna, FRANCE, OCEANIA" }, // Wallis and Futuna
  { "🇹🇻", "🇹🇻: tv, tuv, Tuvalu, OCEANIA" },
  { "🇦🇸", "🇦🇸: as, asm, Americansamoa, USA, POLYNESIA, OCEANIA" }, // American Samoa
  { "🇵🇳", "🇵🇳: pn, pcn, Pitcairn, UK, POLYNESIA, OCEANIA" }, // Pitcairn Islands
  { "🇵🇼", "🇵🇼: pw, plw, Palau, MICRONESIA, OCEANIA" },

  { "🇯🇪", "🇯🇪: je, jey, Jersey, FRANCE" },
  
  { "🇦🇶", "🇦🇶: aq, ata, Antarctica, ANTARCTICA" },

  { "🇳🇫", "🇳🇫: nf, nfk, NorFolkIsland, AUSTRALASIA, POLYNESIA, OCEANIA" }, // Norfolk Island
  { "🇨🇰", "🇨🇰: ck, cok, Cookisland, NEWZEALAND, POLYNESIA, OCEANIA" }, // Cook Islands
  { "🇳🇿", "🇳🇿: nz, nzl, NewZealand, NEWZEALAND, AUSTRALASIA, OCEANIA" }, // New Zealand
  { "🇳🇺", "🇳🇺: nu, niu, Niue, NEWZEALAND, POLYNESIA, OCEANIA" },
  { "🇹🇰", "🇹🇰: tk, tkl, Tokelau, NEWZEALAND, POLYNESIA, OCEANIA" },
  { "🇹🇴", "🇹🇴: to, ton, Tonga, POLYNESIA, OCEANIA" },
  
  // still missing
  
  { "🇮🇴", "🇮🇴: io, iot, BritishIndianOcean" }, // British Indian Ocean Territory
  { "🇹🇫", "🇹🇫: tf, atf, FrenchSouthernandaAtarctic" }, // French Southern and Antarctic Lands
  { "🇬🇬", "🇬🇬: gg, ggy, Guernsey, GUERNSEY" },
  { "🇭🇲", "🇭🇲: hm, hmd, HeardandMacDonaldsIslands" }, // Heard Island and McDonald Islands
  { "🇺🇲", "🇺🇲: um, umi, UsMinorOutlyingIslands, US" }, // United States Minor Outlying Islands
};

/*
 *  flags changed
 */
static int flagidflags = 0; // dont display ids

static int idsall = 1;

/*
 *  flag for each id
 */
static char flagids[sizeof(idsflags) / sizeof(idsflags[0])];

int newressu_toggleflag(unsigned char *flag)
{
  int c, ok;
  
  if(!strcmp(flag, "ALL")) {
    idsall = !idsall;
    for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
      flagids[c] = idsall;
    }
    flagidflags = 1; // display flags
    ok = 1; // one flag toggled
  } else {
    ok = 0;
    for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
      if(newressu_strstr(idsflags[c].flags, flag)!=NULL) {
	flagids[c] = !flagids[c];
	flagidflags = 1; // display flags
	ok = 1; // one flag toggled
      }
    }
    //if(ok)
    //  fprintf(stdout,"\n");
  }
  return(ok);
}

#ifdef FORT
#include "fort.h"
#endif

void clock_bytes(int size, unsigned char *buffer) // JariK 2024
{
  int c;
  
  for(c = 0; c < size; c++)
    buffer[c] = ressu_clock();
}

static unsigned char samplefilename[128] = "newressusample%d.rnd";

int input = INPUT_RESSU;
unsigned char *input_str = "ressu";

int base = -1;

static unsigned char newressutab[GENT_SIZE]; // orig 1024 
static unsigned int newressutab_pos = 0;

void newressu_clear()
{
  memset(newressutab, 0, sizeof(newressutab)); // forget newressutab
}

#define aDEBUG22 2
#define aDEBUG18 2

int newressu_genbyte()
{
  unsigned char ch;

  if(newressutab_pos == 0) {
#ifdef DEBUG22
    ressu_dump("oldgent", 32, newressutab, 32); // first 32 bytes
#endif

    newressu_clear();
    
    if(input == INPUT_RESSU) // ressu prod
      ressu_genbytes(sizeof(newressutab), newressutab);

#ifdef SHA256
    else if(input == INPUT_PSEUDORESSU) // pseudoressu
      pseudoressu_bytes(sizeof(newressutab), newressutab);
    
#endif
#ifdef SHA256
    else if(input == INPUT_RESSUTWIST) // ressu w twist
      ressutwist_bytes(sizeof(newressutab), newressutab);

#endif
#ifdef SHA256
    else if(input == INPUT_PSEUDORANDOM) // pseudoressu
      pseudorandom_bytes(sizeof(newressutab), newressutab);
    
#endif
    else if(input == INPUT_RESSU2) // ressu2
      ressu2_bytes(sizeof(newressutab), newressutab);
    
    else if(input == INPUT_PSEUDORESSU2) // ressu2
      pseudoressu2_bytes(sizeof(newressutab), newressutab);
#ifdef SHA256
    else if(input == INPUT_RESSU2TWIST) // ressu w twist
      ressu2twist_bytes(sizeof(newressutab), newressutab);

#endif
    else if(input == INPUT_SINGLE) // ressu2
      single_bytes(sizeof(newressutab), newressutab);
    
    else if(input == INPUT_RESSU3) // ressu2
      ressu3_bytes(sizeof(newressutab), newressutab);
    
    else if(input == INPUT_FASTRESSU) // ressu_fast
      ressu_genbytes_fast(sizeof(newressutab), newressutab);

    else if(input == INPUT_SINGLERESSU) // ressu single
      ressu_genbytes_single(sizeof(newressutab), newressutab);

    else if(input == INPUT_STREAM) // stream
      stream_bytes(sizeof(newressutab), newressutab);

    else if(input == INPUT_TEST) // test generator
      test_bytes(sizeof(newressutab), newressutab);

#ifdef FORT
    else if(input == INPUT_FORT) // ressu fort
      fort_random_data(sizeof(newressutab), newressutab);

    else if(input == INPUT_FORTXOR) // ressu fort
      fort_random_data_xor(sizeof(newressutab), newressutab);

#endif
#ifdef USE_RDRAND
    else if(input == INPUT_RDRAND) // intel rdrand
      rdrand_bytes(sizeof(newressutab), newressutab);

#endif
#ifdef USE_RDSEED
    else if(input == INPUT_RDSEED) // intel rdseed
      rdseed_bytes(sizeof(newressutab), newressutab);

#endif
    else if(input == INPUT_URANDOM) // urandom
      urandom_bytes(sizeof(newressutab), newressutab);

#ifdef USE_RANDOM
    else if(input == INPUT_RANDOM) // random
      random_bytes(sizeof(newressutab), newressutab);

#endif
    else if(input == INPUT_CLOCK) // clockstream
      clock_bytes(sizeof(newressutab), newressutab);

    else {
      fprintf(stdout,"%s: mode '%d'(%s) not available\n",
	      procname, input, input_str);
      exit(2);
    }
#ifdef DEBUG22
    ressu_dump("newgent", 32, newressutab, 32); // first 32 bytes
#endif
  } // if(newressutab_pos==0
  ch = newressutab[newressutab_pos];
  newressutab_pos = (newressutab_pos + 1) % sizeof(newressutab);

#ifdef DEBUG18
  fprintf(stdout, "{%02x}", ch);
#endif
  return(ch);
}

static unsigned char *basedigits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"; // 64 chars

void fprintfbase(FILE *fp1, unsigned long long ll2, int base) // JariK 2023
{
  int count;
  unsigned long long ll, divider;

  if(base == 2)
    fprintf(fp1,"0b");
  else if(base == 8)
    fprintf(fp1,"0o");
  else if(base == 10)
    fprintf(fp1,"0d");
  else if(base == 16)
    fprintf(fp1,"0x");
  
  ll = ll2;
  divider = 1;
  count = 0;

  for(;;) { // count digits
    ll /= base;
    count++;
    if(ll == 0)
      break;
    divider *= base; // do not count last digit
  }

  while(count > 0) { // print digits
    fprintf(fp1,"%c", basedigits[(ll2 / divider) % base]);
    divider /= base;
    count--;
  }
}

#define aDEBUG24 2
  
unsigned long newressu_gen_limit(unsigned long limit) // JariK 2022
{
  int c;
  unsigned long word;
  static unsigned long lastlimit = 0, highlimit;
  static int bytes;

  if(lastlimit != limit) { // if limit changes, calculate new highlimit and bytes
    lastlimit = limit;
    if(limit <= 0x100) { // one byte
      // highest multiplier of limit that fits to needed bytes
      highlimit = (0x100 / limit) * limit;
      // number of bytes needed
      bytes = 1;

    } else if(limit <= 0x10000) { // two bytes
      highlimit = (0x10000 / limit) * limit;
      bytes = 2;

    } else if(limit <= 0x1000000) { // three bytes
      highlimit = (0x1000000 / limit) * limit;
      bytes = 3;

    } else if(limit <= 0x100000000) { // four bytes
      highlimit = (0x100000000 / limit) * limit;
      bytes = 4;

    } else if(limit <= 0x10000000000) { // five bytes
      highlimit = (0x10000000000 / limit) * limit;
      bytes = 5;

    } else if(limit <= 0x1000000000000) { // six bytes
      highlimit = (0x1000000000000 / limit) * limit;
      bytes = 6;

    } else if(limit <= 0x100000000000000) { // seven bytes
      highlimit = (0x100000000000000 / limit) * limit;      
      bytes = 7;

    } else { // if(limit <= 0xffffffffffffffff) {
      highlimit = (0xffffffffffffffff / limit) * limit;      
      bytes = 8;

    }
  } // if(lastlimit != limit

  for(;;) {
    word = 0;
    for(c = 0; c < bytes; c++)
      word = word << 8 | newressu_genbyte();
    if(word < highlimit)
      break;
  }

#define aDEBUG34

#ifdef DEBUG34
  fprintf(stdout,"limit:%lu", limit);
  fprintf(stdout,", highlimit:%lu", highlimit);
  fprintf(stdout,", bytes:%d", bytes);
  fprintf(stdout,", word:%lu", word);
  fprintf(stdout,", word%%limit:%lu", (unsigned long) word % limit);
  fprintf(stdout,", base:");
  if(base == -1)
    fprintfbase(stdout, word % limit, 16);
  else
    fprintfbase(stdout, word % limit, base);
  fprintf(stdout,", base:0o%lo", word % limit);
  fprintf(stdout,", base:0d%lu", word % limit);
  fprintf(stdout,", base:0x%lx", word % limit);
  fprintf(stdout,"\n");
#endif
  
  word %= limit;
  
#ifdef DEBUG24
  fprintf(stdout,"/");
  fprintf(stdout,"%d bytes: ", bytes);
  fprintf(stdout,"[");
  if(base == -1)
    fprintfbase(stdout, word, 16);
  else
    fprintfbase(stdout, word, base);
  fprintf(stdout,"]");
  fprintf(stdout,"/");
  fflush(stdout);
#endif

  return(word);
}

static int cursor_on = 0;
unsigned char cursor[4] = { '|', '/', '-', '\\' };
long int prev_secs = -1;
int crs = 0;

void stat_line_cursor_start()
{
  fprintf(stderr,"%c", cursor[crs]);
  fflush(stderr);
  //prev_secs = -1;
  cursor_on = 1;
}

void stat_line_cursor()
{
  long int secs;

  secs = time(NULL) % sizeof(cursor);
  if(prev_secs != secs) {
    if(prev_secs != -1) 
      crs = (crs + 1) % sizeof(cursor);
    fprintf(stderr,"\b%c", cursor[crs]);
    fflush(stderr);
    prev_secs = secs;
  }
}

void stat_line_cursor_remove()
{
  if(cursor_on) {
    fprintf(stderr, "\b \b");
    fflush(stderr);
    //prev_secs = -1;
  }
  cursor_on = 0;
}

#include <stdarg.h>

#define aDEBUG31 2

unsigned char *procname = NULL;

static unsigned char *prev_stat_line = NULL;
static unsigned char *stat_line = NULL;
static size_t stat_line_length = 0;

static void stat_line_begin()
{
  if(stat_line != NULL)
    stat_line[0] = '\0';
}

static void stat_line_printf(const unsigned char *format, ...)
{
  int count;
  va_list args;
  static unsigned char *buffer = NULL;
  static size_t buffer_length = 0;

  va_start(args, format);
  count = vsnprintf(buffer, buffer_length, format, args) + 1;
  va_end(args);

  if(buffer_length < count) {
    buffer_length = count;
    buffer = realloc(buffer, buffer_length);
    va_start(args, format);
    count = vsnprintf(buffer, buffer_length, format, args) + 1;
    va_end(args);
  }

  count = 0;
  if(stat_line != NULL)
    count += strlen(stat_line);
  count += strlen(buffer);
  count++;
  
  if(stat_line_length < count) {
    unsigned char *stat_line2 = stat_line;
    stat_line_length = count;
    stat_line = realloc(stat_line, stat_line_length);
    prev_stat_line = realloc(prev_stat_line, stat_line_length);
    if(stat_line2 == NULL) {
      stat_line[0] = '\0';
      prev_stat_line[0] = '\0';
    }
  }
  strcat(stat_line, buffer);
}

#define READABLE_NUMBER_BIN 2

#ifdef READABLE_NUMBER_BIN
#define READABLE_NUMBER_HIGH 1023
#define READABLE_NUMBER_DIVIDER 1024
#else
#define READABLE_NUMBER_HIGH 999
#define READABLE_NUMBER_DIVIDER 1000
#endif

#define READABLE_NUMBER_WIDTH 32

static void stat_line_get_readable(unsigned char buf10[10], unsigned long long length)
{
  int c, low;
  double length2;

  // B = byte
  // K = kilo   10^3   2^10
  // M = mega   10^6   2^20
  // G = giga   10^9   2^30
  // T = tera   10^12  2^40
  // P = peta   10^15  2^50
  // E = exa    10^18  2^60
  // Z = zetta  10^21  2^70
  // Y = yotta  10^24  2^80

  char units[] = "BKMGTPEZY";

  strcpy(buf10, "***");
  low = 0;

  for(c = 0; length >= low &&
      c < sizeof(units) - 1; c++) {
    if(length >= low &&
       length <= READABLE_NUMBER_HIGH) {
      if(units[c] == 'B')
        sprintf(buf10, "%lld", length);
      else if(units[c] == 'K' ||
	      units[c] == 'M' ||
	      units[c] == 'G' ||
	      units[c] == 'T')
	sprintf(buf10, "%.3f", length2);
      else if(length == length2)
	sprintf(buf10, "%lld", length);
      else
	sprintf(buf10, "%.1f", length2);

      if(strchr(buf10, '.') != NULL) {
	int d;
	d = strlen(buf10) - 1;
	while(d > 3 && isdigit(buf10[d])) {
	  buf10[d] = '\0';
	  d--;
	}
	if(buf10[strlen(buf10)-1] == '.')
	  buf10[strlen(buf10)-1] = '\0';
      }

      if(units[c] != 'B') {
	char unit[10];
	sprintf(unit,"%cB",units[c]);
	strcat(buf10, unit);
      }
      break;
    }
    length2 = (double)length / READABLE_NUMBER_DIVIDER;
    length /= READABLE_NUMBER_DIVIDER;
    low = 1;
  }
}

static void stat_line_readable(unsigned long long length)
{
  unsigned char buf10[10];
  stat_line_get_readable(buf10, length);
  stat_line_printf("%s", buf10);
}

static void stat_line_dhms(unsigned long long printleft)
{
  unsigned long int left2;
  unsigned long int temp;
  int timeprinted = 0;
  
  left2 = printleft;
  temp = left2 / (24 * 3600); // days
  if(temp > 0) {
    timeprinted = 1;
    stat_line_printf(" %dd", temp);
    left2 -= temp * (24 * 3600);
  }
  
  temp = left2 / 3600; // hours
  if(temp > 0 || timeprinted) {
    timeprinted = 1;
    //hoursprinted = 1;
    stat_line_printf(" %02dh", temp);
    left2 -= temp * 3600;
  }
  
  temp = left2 / 60; // minutes
  if(temp > 0 || timeprinted) {
    timeprinted = 1;
    stat_line_printf(" %02dm", temp);
    left2 -= temp * 60;
  }
  
  temp = left2; // seconds
  if(!timeprinted) {
    stat_line_printf(" %d seconds", temp);
  }
}

void stat_line_end()
{
  int c, d;

  if(stat_line != NULL && strcmp(prev_stat_line, stat_line)) { // status line changed
    stat_line_cursor_remove();
#ifdef DEBUG31
    fprintf(stderr, "\n");
#else
    fprintf(stderr, "\r");
#endif  

    fprintf(stderr,"%s", stat_line);
    fflush(stderr);

    // previous line longer than this one,
    // overwrite with spaces and backspace to
    // end
    
    d = strlen(prev_stat_line) - strlen(stat_line) + 1; // cursor too

    if(d > 0) { // previous line longer
      for(c = 0; c < d; c++) {
#ifdef DEBUG31
	fprintf(stderr, "*");
#else
	fprintf(stderr, " "); // print spaces
#endif
      }
#ifndef DEBUG31
      for(c = 0; c < d; c++)
	fprintf(stderr, "\b"); // and backspaces
#endif
    }
    strcpy(prev_stat_line, stat_line);
    //if(strlen(stat_line) > 0)
    //stat_line_cursor_start();
    //stat_line_cursor();
  }
}

#define KILO 1024

void readablelonglong(FILE *fp1, unsigned long long ll2) // 2023 JariK
{
  int c;
  unsigned long long multiplier, ll = ll2;
  
  // B = byte
  // K = kilo   10^3   2^10
  // M = mega   10^6   2^20
  // G = giga   10^9   2^30
  // T = tera   10^12  2^40
  // P = peta   10^15  2^50
  // E = exa    10^18  2^60
  // Z = zetta  10^21  2^70
  // Y = yotta  10^24  2^80

  char units[] = "BKMGTPEZY";

  c = 0;
  multiplier = 1;
  while(ll >= KILO) {
    ll /= KILO;
    multiplier *= KILO;
    c++;
  }

  if(ll * multiplier != ll2)
    fprintf(fp1,"~"); // approximately

  fprintf(fp1,"%llu%c", ll, units[c]);
}

void fprintfcharacter(FILE *fp1, unsigned char *p) // 2023 JariK
{
  fputc(*p, fp1); // print first char
  if(*p > 0xbf) { // first char utf8
    p++;
    for(;;) { // print rest of the utf8 chars
      if(*p > 0xbf || // new utf8 character
	 *p < 0x80 || // ascii character
	 *p == '\0') // end of string
	break;
      fputc(*p, fp1);
      p++;
    }
  }
}

int getdigit(unsigned char *p) // 2023 JariK
{
  int digit;
  
  if(*p >= '0' && *p <= '9')
    digit = *p - '0';
  else if(*p >= 'a' && *p <= 'z')
    digit = (*p - 'a') + 10;
  else if(*p >= 'A' && *p <= 'Z')
    digit = (*p - 'A') + 10;
  else
    digit = -1; // not found, illegal

  return(digit);
}

#define DEBUG32

//#define KILO 1000
#define KILO 1024

unsigned long long getlonglong(unsigned char *p2) // 2023 JariK
{
  int digit, base = 10;
  unsigned char *p = p2;
  unsigned long long totll, ll, prevll, multiplier;
  
  totll = 0;

  while(*p != '\0') { // works also: 1g100m & 1m20k and 1t1t etc...

    unsigned char *prevp = p;
    
    if(!strncmp("0x", p, 2)) {
      base = 16;
      p += 2;
      
    } else if(!strncmp("0d", p, 2)) {
      base = 10;
      p += 2;
      
    } else if(!strncmp("0o", p, 2)) {
      base = 8;
      p += 2;
      
    } else if(!strncmp("0b", p, 2)) {
      base = 2;
      p += 2;
      
    }
    
    ll = 0;
    while((digit = getdigit(p)) != -1 && digit < base) {
      ll = ll * base + digit;
      p++;
    }
    
    multiplier = 1;
    
    if(*p == 'k' || *p == 'K') {
      multiplier = KILO;
      p++;
      
    } else if(*p == 'm' || *p == 'M') {
      multiplier = (KILO * KILO);
      p++;
      
    } else if(*p == 'g' || *p == 'G') {
      multiplier = (KILO * KILO * KILO);
      p++;
      
    } else if(*p == 't' || *p == 'T') {
      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO);
      p++;
      
    } else if(*p == 'p' || *p == 'P') {
      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO);
      p++;
      
    } else if(*p == 'e' || *p == 'E') {
      multiplier = ((unsigned long long)KILO * KILO * KILO * KILO * KILO * KILO);
      p++;
      
    }
    
    prevll = ll;
    ll *= multiplier;
    if(ll / multiplier != prevll) {
      fflush(stdout);
      fprintf(stderr,"%s: multiply overflow", procname);
      fprintf(stderr,", string:'%s'", p2);
      fprintf(stderr,", digit:'");
      fprintfcharacter(stderr, p);
      fprintf(stderr,"'");
      fprintf(stderr,", value: %d", digit);
      fprintf(stderr,", base: %d", base);
      fprintf(stderr,", ll: %llu", prevll);
      fprintf(stderr,", multiplier: %llu", multiplier);
      fprintf(stderr,"\n");
      fflush(stderr);
    }
  
    if(*p == 'b' || *p == 'B') // remove last b (for bytes in 1tb, 1gb or 1mb)
      p++;
    
    totll += ll;

#ifdef DEBUG32
    fprintf(stderr,"string:'%s'", p2);
    fprintf(stderr,", base:%d(", base);
    readablelonglong(stderr, base);
    fprintf(stderr,")");
    fprintf(stderr,", multiplier:%llu(", multiplier);
    readablelonglong(stderr, multiplier);
    fprintf(stderr,")");
    fprintf(stderr,", prevll:%llu(", prevll);
    readablelonglong(stderr, prevll);
    fprintf(stderr,")");
    fprintf(stderr,", ll:%llu(", ll);
    readablelonglong(stderr, ll);
    fprintf(stderr,")");
    fprintf(stderr,", totll:%llu(", totll);
    readablelonglong(stderr, totll);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
#endif
    
    if(prevp == p) // no progress
      break;
  }
  
  if(*p != '\0') {
    fflush(stdout);
    fprintf(stderr,"%s: illegal digit", procname);
    fprintf(stderr,", string:'%s'", p2);
    fprintf(stderr,", digit:'");
    fprintfcharacter(stderr, p);
    fprintf(stderr,"'");
    fprintf(stderr,", value: %d", digit);
    fprintf(stderr,", base: %d(", base);
    readablelonglong(stderr, base);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
    fflush(stderr);
  }

  return(totll);
}

static int zero = 1, sspace = 0, snewline = 0,
  scrlf = 1, chars = 72, pchars = 0, charwidth = 1,
  charspaces = 0, words = 0, pwords = 0, cwords = 0,
  plinesdigits = 5, slineno = 1, screen = 0,
  quiet = 0, sort = 0, unique = 0,
  flagprintdigits = 0;

static int calc_spaces()
{
  int spaces;

  spaces = 0;
  
  if(sspace >= 2 &&
     // space between word groups
     ( (cwords > 0 && cwords % sspace == 0) ||
       // space after linenumber
       // are not printed if
       // not printing linenumber
       (slineno && cwords == 0) ) )
    spaces++;
    
  if(sspace &&
     // space between words
     ( (cwords > 0) ||
       // space after linenumber
       (slineno && cwords == 0) ) ) 
    spaces++;

  return(spaces);
}

static void print_spaces(char spacechar)
{
  int sp;

  for(sp = calc_spaces(); sp > 0; sp--)
    fputc(spacechar, stdout);
}

static long long lines = 10, plines = 0, ptotallines = 0;

void printcolumns(int offset, int base, int startwith, int columns, int *clines) // 2023 JariK
{
  //---------11111111112222222222333333333344444444445555555555666666666677
  //12345678901234567890123456789012345678901234567890123456789012345678901
  //=======================================================================
  //00000 86747100388687087416829400778878989202760594993130062980826178851
  //00001 36862623069143814543525935285460059703805218323534266522497684582
  
  int c, d, digit, nonzero;
  unsigned char digits[0x10] = "0123456789abcdef";

  *clines = 0;

  if(base == 2)
    c = 1 << 12;
  else if(base == 8)
    c = 01000000;
  else if(base == 10)
    c = 1000000;
  else if(base == 16)
    c = 0x1000000;
  else {
    fprintf(stdout,"%s: printcolumns():", procname);
    fprintf(stdout," illegal base %d", base);
    fprintf(stdout,"\n");
    exit(1);
  }

  for(;c >= 1; c /= base) { // lines, 100000's, 10000's, 1000's ... 1's
    if(c >= columns)
      continue;

    for(d = 0; d < offset; d++)
      fprintf(stdout," "); // spaces in beginning of row

    nonzero = 0;
    
    for(d = startwith; d < columns + startwith; d++) { // column numbers
      digit = (d / c) % base;
      if(digit != 0)
	nonzero = 1;
      if(nonzero || c == 1)
	fprintf(stdout,"%c", digits[digit]); // nonzero digits after first nonzero
      else
	fprintf(stdout,"-"); // zeroes in beginning of row
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  if(pwords > 0) {
    if(slineno) {
      for(c = 0; c <= plinesdigits; c++) // +1
	fprintf(stdout,"-");
    }
    for(cwords = 0; cwords < pwords; cwords++) {
      print_spaces('-');
      fprintf(stdout,"w");
      if(charwidth == 2)
	fprintf(stdout,"-");
      for(c = 0; c < size - 1; c++) {
	fprintf(stdout,"-");
	if(charwidth == 2)
	  fprintf(stdout,"-");
      }
    }
    fprintf(stdout,"\n");
    (*clines)++;
  }
  for(d = 0; d < offset; d++)
    fprintf(stdout," "); // spaces in beginning of row
  for(d = startwith; d < columns + startwith; d++)
    fprintf(stdout,"=");
  fprintf(stdout,"\n");
  (*clines)++;
}

#ifdef SAMPLE_HASH

void hashfinal2string(unsigned char *hashstring, unsigned char *final)
{
  for(int c = 0; c < HashLen; c++) {
    sprintf(hashstring + 2 * c, "%02x",final[c]);
  }
}

#endif

static int sample = 0, dieharder = 0; // randomness analysis

// try randomness analysis with: $ dieharder -a -g 201 -f newressusample1.rnd > newressusample1.rnd.dieharder

#include <signal.h>

typedef void (*sighandler_t)(int);

void sample_handler()
{
  static int times = 0;

  times++;

  fprintf(stderr,"Ctrl-c pressed %d times\n", times);
  if(times >= 10) {
    signal(SIGINT, SIG_DFL);
    exit(2);
  }
}

#define DEBUG39

#define FILESIZE 3 * 1024 * 1024 * 1024
#define BLOCKSIZE 384 * 1024
#define BLOCKS 8192

unsigned long long filesize = (long long)FILESIZE, blocks = BLOCKS;
unsigned int blocksize = BLOCKSIZE;
int filesize_set = 0, blocks_set = 0, blocksize_set = 0;
int purge = 1;
int purge_set = 0;
unsigned char *filesize_str = NULL, *blocks_str = NULL, *blocksize_str = NULL;


void dump_sample() // & dieharder analysis
{
#define STAT_LINE_SHOW_BLOCK 2 // on by default
#define STAT_LINE_SHOW_WRITTEN 2 // on by default
#define STAT_LINE_SHOW_SPEED 2 // on by default
#define STAT_LINE_SHOW_NOW 2 // on by default
#define STAT_LINE_SHOW_LEFT 2 // on by default
#define STAT_LINE_SHOW_READY 2 // on by default

#define STAT_LINE_LESS_WOBBLE 2 // on by default

#define TIMEFORMAT "%H:%M %Z"
#define TIMEFORMAT2 "%a %H:%M %Z"
#define DATEFORMAT "%a %d %b %Y"
    
  unsigned long long c;
  unsigned char *buffer, filename[128], command[1024];
  
  FILE *fp1;
  
  // find first available filename,
  // or empty "fileslot"
  
  for(c = 1; c <= 999999; c++) {

    sprintf(filename, samplefilename, c);
    
    if((fp1 = fopen(filename, "r")) != NULL) {
      fclose(fp1);
      continue;
    }

    unsigned char filename2[138];

    sprintf(filename2,"%s.dieharder",filename);
    if((fp1 = fopen(filename2, "r")) != NULL) {
      fclose(fp1);
      continue;
    }
#ifdef SAMPLE_HASH
    sprintf(filename2,"%s.sha256",filename);
    if((fp1 = fopen(filename2, "r")) != NULL) {
      fclose(fp1);
      continue;
    }
#endif

    break;
  }

  
  // calculate missing file size parameters
  
  if(!filesize_set)
    filesize = blocks * blocksize;
  else if(!blocksize_set) {
    blocksize = (filesize + blocks - 1) / blocks; // round up
    filesize = blocks * blocksize;
  } else if(!blocks_set) {
    blocks = (filesize + blocksize - 1)/ blocksize; // round up
    filesize = blocks * blocksize;
  }

#define EXFAT_FIX 2 // on for now
  
#ifdef EXFAT_FIX

  if(blocksize > KILO * KILO) { // max "blocksize" 1m (exfat)
    blocksize = KILO * KILO;
    blocks = (filesize + blocksize - 1) / blocksize;
    filesize = blocks * blocksize;
  }

#endif
  
  if(filesize != blocks * blocksize ||
     blocks < 1 || blocksize < 1) {
    fflush(stdout);
    fprintf(stderr,"%s: sample(): mismatched parameters", procname);
    fprintf(stderr,", blocks:%llu(", blocks);
    readablelonglong(stderr, blocks);
    fprintf(stderr,")");
    fprintf(stderr,", blocksize:%u(", blocksize);
    readablelonglong(stderr, blocksize);
    fprintf(stderr,")");
    fprintf(stderr,", filesize:%llu(", filesize);
    readablelonglong(stderr, filesize);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
    fflush(stderr);
    exit(1);
  }
  
  if(filesize / blocks != blocksize) {
    fflush(stdout);
    fprintf(stderr,"%s: sample(): parameter overflow", procname);
    fprintf(stderr,", blocks:%llu(", blocks);
    readablelonglong(stderr, blocks);
    fprintf(stderr,")");
    fprintf(stderr,", blocksize:%u(", blocksize);
    readablelonglong(stderr, blocksize);
    fprintf(stderr,")");
    fprintf(stderr,", filesize:%llu(", filesize);
    readablelonglong(stderr, filesize);
    fprintf(stderr,")");
    fprintf(stderr,"\n");
    fflush(stderr);
    exit(1);
  }

#ifdef DEBUG39
  fprintf(stderr,"blocksize:%u(", blocksize);
  readablelonglong(stderr, blocksize);
  fprintf(stderr,")");
  fprintf(stderr,", blocks:%llu(", blocks);
  readablelonglong(stderr, blocks);
  fprintf(stderr,")");
  fprintf(stderr,", filesize:%llu(", filesize);
  readablelonglong(stderr, filesize);
  fprintf(stderr,")\n");
  fflush(stderr);
#endif

  if((buffer = malloc(blocksize)) == NULL) {
    fprintf(stderr,"%s: sample(): cannot allocate memory (buffer)\n", procname);
    exit(1);
  }
  
#define DEBUG40 2 // default on (for now)
    
#ifdef DEBUG40
  fprintf(stderr,"%s: sample(): writing file", procname);
  fprintf(stderr,", filename:%s", filename);
#ifndef SAMPLE_WRITE
  fprintf(stderr,", no write");
#endif
  fprintf(stderr,"\n");
#endif
  
#ifdef SAMPLE_HASH
  unsigned char digest[HashLen];
  HashCtx hash;

  unlink("sample.deb");
  HashInit(&hash); // calculate hash
#endif

  // variables for stat line fields

  time_t start, now, left, end, took;
  unsigned char speed[10], printspeed[10] = "";

#ifdef STAT_LINE_LESS_WOBBLE

  time_t prevend = -1;
  int countspeed = 0, countend = 0;
  unsigned char prevspeed[10] = "";
  unsigned int calculateleft;

#endif

  time_t printleft = -1, printend = -1;
  int leftprinted = 0;

  unsigned long long clim = 0;
  
  if((fp1 = fopen(filename, "a")) != NULL) {

    // starting time
    
    start = time(NULL);
    
    clim = (unsigned long long) filesize / blocksize;

#ifdef EXFAT_FIX
    int mbinblocks = (1 * KILO * KILO) / blocksize;
    if(mbinblocks == 0)
      mbinblocks = 1;
    fprintf(stderr,"mbinblocks:%d\n", mbinblocks);
#endif
    
    // you have to press ctrl-c 10 times

    signal(SIGINT, sample_handler);
    
    for(c = 0; c < clim; c++) {

      // current time
      
      now = time(NULL);

      // estimate for ending time
      
      end = (time_t)start + ((((double)now - start) / c) * clim);

#ifdef STAT_LINE_LESS_WOBBLE

      calculateleft = 0; 
      if(prevend / 60 == end / 60 &&
	 ++countend >= 30) { // 30 times same minutes --> minutes are real

	printend = end;
	calculateleft = 1;
      } else if(prevend / 60 != end / 60) { // minutes different
	prevend = end;
	countend = 0;
      }

#else
      printend = end;
#endif

      // estimate for time left

      left = printend - now;

#ifdef STAT_LINE_LESS_WOBBLE
      
      static int onlyseconds = 0;
      static long long cstart, cleft, cseconds;
      
      if(onlyseconds || (left > 0 && left < 60)) {
	if(!onlyseconds) {
	  cstart = c;
	  cleft = clim - c;
	  cseconds = left;
	  onlyseconds = 1;
	}

	left = (double) cseconds - ((((double) c - cstart) / cleft) * cseconds);
      }

      if(calculateleft)
	printleft = left;
      
#else
      printleft = left;
#endif

      // speed
      
      if(now - start > 1.0)
	stat_line_get_readable(speed, (unsigned long long)((double)c * blocksize / (now - start)) );
      else
	stat_line_get_readable(speed, (unsigned long long)((double)c * blocksize));

#ifdef STAT_LINE_LESS_WOBBLE

      if(!strcmp(prevspeed, speed) &&
	 ++countspeed >= 3) { // three times same speed --> speed is real
	strcpy(printspeed, speed);
      } else if(strcmp(prevspeed, speed)) {
	strcpy(prevspeed, speed);
	countspeed = 0;
      }

#else
      strcpy(printspeed, speed);
#endif
      
      // print status line:
      // 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
      
      stat_line_begin();
      
      int print = 0;
#ifdef STAT_LINE_SHOW_BLOCK
      
      stat_line_printf("%s", input_str);
      
      // print block from 0 to 8192
      
      stat_line_printf("block %lld", c);
      print = 1;
#endif
      
#ifdef STAT_LINE_SHOW_WRITTEN
      
      // print written
      
      if(print)
	stat_line_printf(", ");
      
      stat_line_printf("written ");
      stat_line_readable((unsigned long)c * blocksize);
      print = 1;
#endif	  
      if(c > 0) {
	
#ifdef STAT_LINE_SHOW_SPEED
	
	// print speed
	
	if(printspeed[0] != '\0') {
	  if(print)
	    stat_line_printf(", ");

	  stat_line_printf("%s/sec", printspeed);
	  print = 1;
	}
#endif
	
#if defined STAT_LINE_SHOW_NOW ||			\
  defined STAT_LINE_SHOW_READY
	char timebuf[128];
#endif
	
#ifdef STAT_LINE_SHOW_READY
	char timebuf2[128];
#endif
	
#ifdef STAT_LINE_SHOW_NOW
	
	// print now
	
	if(print)
	  stat_line_printf(", ");
	
	stat_line_printf("now");
	strftime(timebuf, sizeof(timebuf), TIMEFORMAT2,
		 localtime((time_t *)&now));
	stat_line_printf(" %s", timebuf);
	print = 1;
#endif
	
#ifdef STAT_LINE_SHOW_LEFT
	
	// print left
	
	if(printleft > 0) {

	  if(print)
	    stat_line_printf(", ");

	  stat_line_printf("left");
	  stat_line_dhms(printleft);

	  leftprinted = 1;
	  print = 1;
	}
#endif
	
#ifdef STAT_LINE_SHOW_READY
	
	//unsigned long int end = (int)start + ((((double)now - start) / c) * clim);

	if(printend > 0 && leftprinted) {
	  if(print)
	    stat_line_printf(", ");
	  
	  stat_line_printf("ready at");
	  strftime(timebuf, sizeof(timebuf), DATEFORMAT,
		   localtime((time_t *) & end));
	  strftime(timebuf2, sizeof(timebuf2), DATEFORMAT,
		   localtime((time_t *) & now));
	  if(strcmp(timebuf, timebuf2)) {
	    stat_line_printf(" %s", timebuf);
	  }
	  
	  // print end time
	  
	  strftime(timebuf, sizeof(timebuf), TIMEFORMAT,
		   localtime((time_t *) & printend));
	  stat_line_printf(" %s", timebuf);
	  
	  print = 1;
	}
#endif
      }
      stat_line_end();
      stat_line_cursor_start();
      
      // do the work
      
      stat_line_cursor();

      memset(buffer, 0, blocksize);
            
      if(input == INPUT_RESSU) // ressu prod
	ressu_genbytes(blocksize, buffer);
      
      else if(input == INPUT_PSEUDORESSU) // pseudoressu
	pseudoressu_bytes(blocksize, buffer);
      
      else if(input == INPUT_RESSUTWIST) // ressu w twist
	ressutwist_bytes(blocksize, buffer);
	
      else if(input == INPUT_PSEUDORANDOM) // pseudoressu
	pseudorandom_bytes(blocksize, buffer);

      else if(input == INPUT_PSEUDORESSU2) // pseudoressu
	pseudoressu2_bytes(blocksize, buffer);

      else if(input == INPUT_RESSU2TWIST) // ressu w twist
	ressu2twist_bytes(blocksize, buffer);
	
      else if(input == INPUT_RESSU3) // pseudoressu
	ressu3_bytes(blocksize, buffer);

      else if(input == INPUT_SINGLE) // pseudoressu
	single_bytes(blocksize, buffer);

      else if(input == INPUT_FASTRESSU) // ressu fast
	ressu_genbytes_fast(blocksize, buffer);
      
      else if(input == INPUT_SINGLERESSU) // ressu single
	ressu_genbytes_single(blocksize, buffer);
      
      else if(input == INPUT_STREAM) // ressu stream
	stream_bytes(blocksize, buffer);
      
      else if(input == INPUT_TEST) // test generator
	test_bytes(blocksize, buffer);
      
#ifdef FORT
      else if(input == INPUT_FORT) // ressu fort
	fort_random_data(blocksize, buffer);
      
      else if(input == INPUT_FORTXOR) // ressu fort
	fort_random_data_xor(blocksize, buffer);
      
#endif
#ifdef USE_RDRAND
      else if(input == INPUT_RDRAND) // intel rdrand
	rdrand_bytes(blocksize, buffer);
      
#endif
#ifdef USE_RDSEED
      else if(input == INPUT_RDSEED) // intel rdseed
	rdseed_bytes(blocksize, buffer);
      
#endif
      else if(input == INPUT_URANDOM) // urandom
	urandom_bytes(blocksize, buffer);
      
#ifdef USE_RANDOM
      else if(input == INPUT_RANDOM) // random
	random_bytes(blocksize, buffer);
      
#endif
#ifdef USE_DUMMY
      else if(input == INPUT_DUMMY) {
	// no generator
      }
#endif
      else {
	fprintf(stdout,"\n%s: mode '%d'(%s) not available\n",
		procname, input, input_str);
	exit(2);
      }
#ifdef SAMPLE_HASH
      HashUpdate(&hash, buffer, blocksize); // calculate hash
      FILE *fp4;
      if((fp4 = fopen("sample.deb", "a")) != NULL) {
	fwrite(buffer, blocksize, 1, fp4);
	fclose(fp4);
      }
#endif
#ifdef SAMPLE_WRITE
      if(input != INPUT_DUMMY) {
	fwrite(buffer, 1, blocksize, fp1);
	
#ifdef SAMPLE_SYNC

#ifdef EXFAT_FIX
	if(c % mbinblocks == 0) { // fflush and sync (EXFAT)
	  fflush(fp1);
	  //sync();
	  fsync(fileno(fp1));
	}
#endif

#endif
      } // end of if(input != INPUT_DUMMY
#endif
    } // end of for(c = 0; c < clim; c++
#ifdef SAMPLE_HASH
    HashFinal(digest, &hash); // calculate hash
#endif

    fflush(fp1); // fflush and sync (EXFAT)
    //sync();
    fsync(fileno(fp1));
    
    fclose(fp1);
    
  } else { // if((fp1=fopen
    fprintf(stderr,"%s:", procname);
    fprintf(stderr," sample(): cannot open file");
    fprintf(stderr,", filename: %s", filename);
    fprintf(stderr,"\n");
    exit(2);
  }
  
  // remove last status line

  //stat_line_cursor_remove();
  
  stat_line_begin();
  
  stat_line_printf("\rwrote ");
  stat_line_readable((unsigned long)c * blocksize);
  
  stat_line_printf(", ");
  if(now - start >= 1.0)
    stat_line_readable((unsigned long)((double)c * blocksize / (now - start)) );
  else
    stat_line_readable((unsigned long)c * blocksize);
  stat_line_printf("/sec");

  end = time(NULL);
  took = end - start;
  stat_line_printf(", took");
  stat_line_dhms(took);
  
  //stat_line_printf(", done!");
  stat_line_end();
  stat_line_cursor_remove();
  fprintf(stderr,"\n");
  fflush(stderr);

#ifdef SAMPLE_HASH
  unsigned char filename2[138];
  unsigned char hashstring[2 * HashLen + 1];
  
  hashfinal2string(hashstring, digest);

  sprintf(filename2,"%s.sha256", filename);
  
  fprintf(stderr,"%s: sample(): hashing file", procname);
  fprintf(stderr,", filename:%s", filename);
  fprintf(stderr,", hashfilename:%s", filename2);
  fprintf(stderr,", sha256:%s\n", hashstring);
  
  if((fp1 = fopen(filename2, "a")) != NULL) {
    fprintf(fp1,"%s\n",hashstring);
    fclose(fp1);
  }
  sprintf(command,"sha256sum %s", filename);
  fprintf(stderr,"%s: sample(): checking sha256", procname);
  fprintf(stderr,", filename:%s", filename);
  fprintf(stderr,", command:'%s'\n", command);
  system(command);
#endif

  signal(SIGINT, SIG_DFL);

  memset(buffer, 0, blocksize); // forget buffer

  free(buffer);
  
  if(dieharder) { // randomness analysis
    
    sprintf(command,"dieharder -a -g 201 -f %s > %s.dieharder 2>&1",
	    filename, filename);
    //sprintf(command,"dieharder -a -g 201 -f %s > %s.dieharder", filename, filename);
    fprintf(stderr,"%s: sample(): running dieharder \"%s\"\n",
	    procname, command);
    system(command);
    sprintf(command,"grep \"WEAK\\|FAILED\" %s.dieharder",
	    filename);
    fprintf(stderr,"%s: sample(): grepping dieharder problems \"%s\"\n"
	    , procname, command);
    system(command);

    long long weak;
    sprintf(command,"grep WEAK %s.dieharder", filename);
    weak = command_countlines(command);
    fprintf(stderr,"%s: sample(): calculating WEAK lines", procname);
    fprintf(stderr, ", lines = %lld", weak);
    fprintf(stderr,", \"%s\"\n", command);

    long long failed;
    sprintf(command,"grep FAILED %s.dieharder", filename);
    failed = command_countlines(command);
    fprintf(stderr,"%s: sample(): calculating FAILED lines", procname);
    fprintf(stderr, ", lines = %lld", failed);
    fprintf(stderr,", \"%s\"\n", command);

    sprintf(command,"grep rewound %s.dieharder | tail -n1",
	    filename);
    fprintf(stderr,"%s: sample(): grepping last rewound count \"%s\"\n",
	    procname, command);
    system(command);

    FILE *fp2;
    if((fp2 = fopen("newressudieharder.skk", "a")) != NULL) { //
      fprintf(fp2,"'input' = \"%s\"", input_str);
      if(filesize_str != NULL)
	fprintf(fp2,", 'filesize' = \"%s\"", filesize_str);
      if(blocksize_str != NULL)
	fprintf(fp2,", 'blocksize' = \"%s\"", blocksize_str);
      if(blocks_str != NULL)
	fprintf(fp2,"'blocks' = \"%s\"", blocks_str);
      fprintf(fp2,", 'filename' = \"%s\"", filename);
      fprintf(fp2,", 'weak' = \"%lld\"", weak);
      fprintf(fp2,", 'failed' = \"%lld\"", failed);
      fprintf(fp2,"\n");
      fclose(fp2);
    }
    
    if(purge) {
      fprintf(stderr,"%s: sample(): removing file", procname);
      fprintf(stderr," %s\n", filename);
      unlink(filename);
    }
    exit(0);
  }
}

static unsigned long limit, word, uppercase = 0;
static unsigned char *digits = "0123456789", character[32];
static unsigned char digitstemp[256], *digitsext = NULL;
static unsigned char linenobuf[1024];
static unsigned char *stream_default_key  = "kalakala";
static unsigned char *key = NULL;
static int print_statline = 0, columns = 0, flagdigits = 0;

int help = 0;

//
//  utf8 functions
//

static int utf8characters(unsigned char *buf)
{
  int characters;
  unsigned char *p;
  
  p = buf;
  characters = 0;
  while(*p != '\0') {
    if(*p < 0x80 || // ascii char
       *p > 0xbf) // first utf8 byte
      characters++;
    p++;
  }

  if(flagdigits == 1) // semicolon separated (flags)
    return(characters / 2);
  else
    return(characters);
}

int utf8strings(unsigned char *buf)
{
  int strings = 0;

  unsigned char *p = buf;
  while(*p != '\0') {
    if(*p == ';')
      strings++;
    p++;
  }

  return(strings);
}

#define aDEBUG47 2

int utf8lengths(unsigned char *buf)
{
  int lengths, len, first = 1;
  unsigned char *p;

#ifdef DEBUG47 
  fprintf(stdout,"digits    %s", buf);
  fprintf(stdout,"\nlengths   ");
#endif
  
  p = buf;
  len = 0;
  lengths = -1;
  first = 1;

  while(*p != '\0') {
    if(!first &&
       (*p < 0x80 || // ascii char
	*p > 0xbf)) { // first utf8 byte
#ifdef DEBUG47
      fprintf(stdout,"%d", len);
#endif
      if(lengths == -1)
	lengths = len;
      else if(lengths != len)
	lengths = 0;
      len = 0;
    }
    p++;
    len++;
    first = 0;
  }

#ifdef DEBUG47
  fprintf(stdout,"%d", len);
#endif
  if(lengths == -1)
    lengths = len;
  else if(lengths != len)
    lengths = 0;

#ifdef DEBUG47
  fprintf(stdout,"\nlengths   %d\n\n", lengths);
#endif
  return(lengths);
}

int utf8stringlengths(unsigned char *buf)
{
  int lengths = -1, len;
  unsigned char *p = buf;

  // return(0);
  
  len = 0;
  while(*p != '\0') {
    if(*p == ';') {
      p++;
      if(lengths == -1)
	lengths = len;
      else if(lengths != len)
	lengths = 0;
      len = 0;
    }
    p++;
    len++;
  }

  if(lengths == -1)
    lengths = 0;
  else
    lengths++; // count semicolon also

  return(lengths);
}

#define aDEBUG42 2

static void codetoutf8(unsigned char *buf2, unsigned long long code)
{
  unsigned char *buf;

  buf = buf2;
  if(code <= 0x7f) {
    *buf++ = code;
  } else if(code <= 0x7ff) {            // 110xxxxx 10xxxxxx
    *buf++ = (0xc0 | ((code >> 6) & 0x1f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0xffff) {           // 1110xxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xe0 | ((code >> 12) & 0x0f));
    *buf++ = (0x80 | ((code >> 6) & 0x3f));
    *buf++ = (0x80 | (code & 0x3f));
  } else if(code <= 0x10ffff) {         // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *buf++ = (0xf0 | ((code >> 18) & 0x07));
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffff) {        // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xf8 | ((code >> 24) & 0x03));
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x7fffffff) {       // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfc | ((code >> 30) & 0x01));
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0xfffffffff) {      // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xfe);
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  } else if(code <= 0x3ffffffffff) {    // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
    *buf++ = (0xff);
    *buf++ = (0x80 | ((code >> 36) & 0x3f));      
    *buf++ = (0x80 | ((code >> 30) & 0x3f));      
    *buf++ = (0x80 | ((code >> 24) & 0x3f));      
    *buf++ = (0x80 | ((code >> 18) & 0x3f));      
    *buf++ = (0x80 | ((code >> 12) & 0x3f));      
    *buf++ = (0x80 | ((code >> 6) & 0x3f));      
    *buf++ = (0x80 | ((code & 0x3f)));      
  }
  *buf = '\0';

#ifdef DEBUG42
  int c, print;

  fprintf(stdout,"codepoint: %lx", code);

  fprintf(stdout,", bin:");

  print = 0;
  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
    int bit = (code >> c) & 1;
    if(bit != 0)
      print = 1;
    if(print) {
      fprintf(stdout,"%d", bit);
      if(c > 0 && c % 8 == 0)
	fprintf(stdout,"|");
    }
  }

  fprintf(stdout,", oct:");
  print = 0;
  fprintf(stdout,"%lo", code);

  fprintf(stdout,", utf8: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout,"%02x", buf2[c]);
  }

  fprintf(stdout,", bin: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    if(c > 0)
      fprintf(stdout,"|");
    for(int d = 7; d >= 0; d--) {
      fprintf(stdout,"%d", buf2[c] >> d & 1);
    }
  }

  fprintf(stdout,", oct:");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout," %3o", buf2[c]);
  }
  
  fprintf(stdout,", character: %s", buf2);
  fprintf(stdout,"\n");
#endif
}

#ifdef NOTUSED

#define aDEBUG43 2

static void utf8tocode(unsigned long *code, unsigned char *buf2)
{
  unsigned char *buf;
  
  *code = 0;
  buf = buf2;
  
  if(*buf <= 0x7f) {                  // 0xxxxxxx
    *code = *buf;
  } else if(*buf < 0xc0) {            // 110xxxxx 10xxxxxx
    *code = 0;
  } else if(*buf < 0xe0) {            // 110xxxxx 10xxxxxx
    *code = *buf++ & 0x1f;
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xf0) {            // 1110xxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x0f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf<0xf8) {            // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x07;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfc) {            // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x03;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xfe) {            // 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    *code = *buf++ & 0x01;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf < 0xff) {            // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  } else if(*buf == 0xff) {            // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    buf++;
    *code = *buf++ & 0x3f;
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
    *code = (*code << 6) + (*buf++ & 0x3f);
  }
#ifdef DEBUG43
  int c;

  fprintf(stdout, "character: %s", buf2);

  fprintf(stdout, ", utf8: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout,"%02x", buf2[c]);
  }

  fprintf(stdout, ", bin: ");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    if(c > 0)
      fprintf(stdout, "|");
    for(int d = 7; d >= 0; d--)
      fprintf(stdout, "%d", buf2[c] >> d & 1);
  }

  fprintf(stdout, ", oct:");
  for(c = 0; c < 8; c++) {
    if(buf2[c] == '\0')
      break;
    fprintf(stdout, " %3o", buf2[c]);
  }
  
  fprintf(stdout, ", codepoint: %lx", *code);
  fprintf(stdout, ", bin:");
  int print = 0;
  for(c = (sizeof(code) * 8) - 1; c >= 0; c--) {
    int bit = (*code >> c) & 1;
    if(bit != 0)
      print = 1;
    if(print) {
      fprintf(stdout, "%d", bit);
      if(c > 0 && c % 8 == 0)
	fprintf(stdout, "|");
    }
  }

  fprintf(stdout, ", oct:");
  fprintf(stdout, "%lo", *code);
  
  fprintf(stdout, "\n");
#endif
}

#endif 

int characterlengths = 0; // 0 multiple lengths, x lengths are same

#define aDEBUG55 2

static void utf8getcharactersemi(int size, unsigned char *buf, int n, unsigned char *string)
{
  int d;
  unsigned char *p, *q;
  
  d = 0;
  p = string;
  q = buf;

  // find first byte of character

  if(characterlengths != 0)
    p += characterlengths * n;
  else {
    if(flagdigits) { // semicolon separated (flags)
      while(*p != '\0') {
	if(d == n)
	  break;
	if(*p == ';') {
	  d++;
	}
	p++;
      }
    } else { // else if(flagdigits)
      while(*p != '\0') {
	if(*p < 0x80 || // ascii char
	   *p > 0xbf) { // first utf8 char
	  if(d == n)
	    break;
	  d++;
	}
	p++;
      }
    }
  }
  //fprintf(stdout,"%d***%s\n",d,p);

  // copy first byte and rest
  // of character

  if(flagdigits) { // semicolon separated (flags)
    while(*p != '\0') {
      if(*p == ';')
	break;
      *q++ = *p++; // copy first byte
    }
  } else {
    if(*p != '\0') {
      *q++ = *p; // copy first byte
      if(*p > 0xbf) { // if first is utf8 char
	p++;
	for(;;) {
	  if(*p > 0xbf || // first utf8 char
	     *p < 0x80 || // ascii char
	     *p == '\0')  // end of file
	    break;
	  *q++ = *p++; // copy rest of the bytes
	}
      }
    }
  }

  *q = '\0';
  //fprintf(stdout,"character: `%s`\n", buf);

#ifdef DEBUG56
  fprintf(stdout,"%s: utf8getcharacter:", procname);
  fprintf(stdout," string: %s", string);
  fprintf(stdout,", n: %d", n);
  fprintf(stdout,", character: %s", buf);
  fprintf(stdout,", characterlengths: %d", characterlengths);
  fprintf(stdout,"\n");
#endif
}

static void utf8getcharacter(int size, unsigned char *buf, int n, unsigned char *string)
{
  int d;
  unsigned char *p, *q;
  
  d = 0;
  p = string;
  q = buf;

  // find first byte of character

  if(characterlengths != 0)
    p += characterlengths * n;
  else {
    while(*p != '\0') {
      if(*p < 0x80 || // ascii char
	 *p > 0xbf) { // first utf8 char
	if(d == n)
	  break;
	d++;
      }
      p++;
    }
  }
  //fprintf(stdout,"%d***%s\n",d,p);

  // copy first byte and rest
  // of character

  if(*p != '\0') {
    *q++ = *p; // copy first byte
    if(*p > 0xbf) { // if first is utf8 char
      p++;
      for(;;) {
	if(*p > 0xbf || // first utf8 char
	   *p < 0x80 || // ascii char
	   *p == '\0')  // end of file
	  break;
	*q++ = *p++; // copy rest of the bytes
      }
    }
  }

  *q = '\0';

#ifdef DEBUG56
  fprintf(stdout,"%s: utf8getcharacter:", procname);
  fprintf(stdout," string: %s", string);
  fprintf(stdout,", n: %d", n);
  fprintf(stdout,", character: %s", buf);
  fprintf(stdout,", characterlengths: %d", characterlengths);
  fprintf(stdout,"\n");
#endif
}

#define aDEBUG56 2

static void utf8getcharacter1(int size, unsigned char *buf, int n, unsigned char *string)
{
  unsigned char *p, *q;
  
  p = string;
  q = buf;

  // find first byte of character

  p += n;

  // copy first byte and rest
  // of character
  
  if(*p != '\0') {
    *q++ = *p; // copy first byte
    if(*p > 0xbf) { // if first is utf8 char
      p++;
      for(;;) {
	if(*p > 0xbf || // first utf8 char
	   *p < 0x80 || // ascii char
	   *p == '\0')  // end of file
	  break;
	*q++ = *p++; // copy rest of the bytes
      }
    }
  }
  *q = '\0';
  
#ifdef DEBUG56
  fprintf(stdout,"%s: utf8getcharacter:", procname);
  fprintf(stdout," string: %s", string);
  fprintf(stdout,", n: %d", n);
  fprintf(stdout,", character: %s", buf);
  fprintf(stdout,", characterlengths: %d", characterlengths);
  fprintf(stdout,"\n");
#endif
}

#define aDEBUG45 2

int digitscount = 10;

// display word in "digits" base (random data)

static void out_word(int size, unsigned char *buf, unsigned char *digits, unsigned long word2) // 8.5.2021 JariK
{
  int c, d, len;
  unsigned long word;
  unsigned char string[1024], character[128];

  //digitscount = utf8characters(digits);
  word = word2;
  len = 0;
  string[0] = '\0';

  if(word == 0 || digitscount < 2) {
    // zero
    utf8getcharactersemi(sizeof(character), character, 0, digits);
    if(len + strlen(character) < sizeof(string)) {
      strcat(string, character);
      len += strlen(character);
    }
  } else {
    // non zero
    while(word > 0) {
      utf8getcharactersemi(sizeof(character), character, word%digitscount, digits);
      if(len + strlen(character) < sizeof(string)) {
	strcat(string, character);
	len += strlen(character);
      }
      word /= digitscount;
    }
  }

#ifdef DEBUG45
  fprintf(stdout,"]\n%s: out_word a:", procname);
  fprintf(stdout," orig string: %s", string);
#endif
  
  // reverse string

  if(flagdigits) // semicolon separated (flags)
    strcpy(buf, string);
  else {
    *buf = '\0';
    len = 0;
    d = utf8characters(string);
    for(c = d - 1; c >= 0; c--) {
      utf8getcharacter(sizeof(character), character, c, string);
      if(len + strlen(character) < size) {
	strcat(buf, character);
	len += strlen(character);
      }
    }
  }

#ifdef DEBUG45
  fprintf(stdout," reverse string: %s", string);
  //fprintf(stdout,", digits: %s", digits);
  fprintf(stdout,", int: %lu", word2);
  fprintf(stdout,"\n[");
#endif
}

// display word in decimal (10-base) (line number)

static void out_word_10(int size, unsigned char *buf, unsigned long word2) // 8.5.2021 JariK
{
  int c, d, len;
  unsigned long word;
  unsigned char string[128], character[32];
  unsigned char *digits10 = "0123456789";
  int digitscount = 10;
  
  //digitscount = utf8characters(digits);
  word = word2;
  len = 0;
  string[0] = '\0';

  if(word == 0 || digitscount < 2) {
    // zero
    utf8getcharacter1(sizeof(character), character, 0, digits10);
    if(len+strlen(character) < sizeof(string)) {
      strcat(string, character);
      len += strlen(character);
    }
  } else {
    // non zero
    while(word > 0) {
      utf8getcharacter1(sizeof(character), character, word % digitscount, digits10);
      if(len + strlen(character) < sizeof(string)) {
	strcat(string, character);
	len += strlen(character);
      }
      word /= digitscount;
    }
  }

  // reverse string
  
  *buf = '\0';
  len = 0;
  d = utf8characters(string);
  for(c = d - 1;c >= 0; c--) {
    utf8getcharacter1(sizeof(character), character, c, string);
    if(len + strlen(character) < size) {
      strcat(buf, character);
      len += strlen(character);
    }
  }

#ifdef DEBUG45
  fprintf(stdout,"]\n%s: out_word b:", procname);
  fprintf(stdout," reverse string: %s", string);
  //fprintf(stdout,", digits: %s", digits);
  fprintf(stdout,", int: %lu", word2);
  fprintf(stdout,"\n[");
#endif
}

static void in_word(unsigned long *word, unsigned char *digits, unsigned char *buf)
{
  int c, d, e, f, ok;
  unsigned char character[32], character2[32];

  *word = 0;
  d = utf8characters(buf);
  if(flagdigits) // semicolon separated (flags)
    f = utf8strings(digits);
  else // not
    f = utf8characters(digits);
    
  for(c = 0; c < d; c++) {
    utf8getcharacter(sizeof(character2), character2, c, buf);
    ok = 0;
    for(e = 0; e < f; e++) {
      utf8getcharactersemi(sizeof(character), character, e, digits); // semi added
      if(!strcmp(character, character2)) {
	ok = 1;
	break;
      }
    }
    if(ok) {
      *word = ((*word) * f) + e;
    } else {
      fprintf(stdout,"%s: in_word:", procname);
      fprintf(stdout," illegal digit '%s'\n", character2);
    }
  }

#ifdef DEBUG45
  fprintf(stdout,"%s: in_word:", procname);
  fprintf(stdout," word: %lu", *word);
  //fprintf(stdout,", digits: %s", digits);
  fprintf(stdout,", string: %s", buf);
  fprintf(stdout,"\n");
#endif

}

//
// lotto functions
//

static void line_clear(int *len, unsigned char **buf)
{
  if(*len < 1) {
    *len = 129;
    *buf = realloc(*buf, *len);
  }
  **buf = '\0';
}

static int line_add_string_sort(int *len, unsigned char **buf, unsigned char *string)
{
  int cmp, count, add;
  unsigned char *p;

  p = *buf;
  add = 1;
  while(*p != '\0') {
    cmp = strncmp(string, p, strlen(string));
    if(cmp > 0) {
      while(*p != ' ' && *p != '\0') // find next space
	p++;
      while(*p == ' ' && *p != '\0') // find next non space
	p++;
    } else if(cmp == 0) {
      add = 0;
      break;
    } else {
      break;
    }
  }

  if(add) {
    count = strlen(*buf) + strlen(string) +1 +1;
    if(*buf == NULL || count > *len) {
      int diff = p - *buf;
      *len = *len + 128;
      *buf = realloc(*buf, *len);
      p = *buf + diff;
    }
    memmove(p + strlen(string) + 1, p, strlen(p) + 1);
    memmove(p, string, strlen(string));
    p += strlen(string);
    *p = ' ';
  }

  return(add);
}

static void line_get_string(int len, unsigned char *buf,
			    int n, unsigned char *string)
{
  int e, ok, count;
  unsigned char *p, *q;

  ok = 0;
  p = string;
  e = 0;

  while(*p != '\0') {
    if(e == n) {
      ok = 1;
      break;
    }
    while(*p != ' ' && *p != '\0') // find next space
      p++;
    while(*p == ' ' && *p != '\0') // find next non space
      p++;
    e++;
  }
  if(ok) {
    q = buf;
    count = 0;
    while(*q != ' ' && *q != '\0') {
      if(++count < len)
	*q++ = *p;
      p++;
    }
    *q = '\0';
  } else {
    buf[0] = '\0';
  }
}

#define DEBUG59 2 // default is on for now

#ifdef DEBUG59
static int utf8 = 0;
#endif

#ifdef DEBUG51
static int limitsize = 0;
#endif

#define aDEBUG51 2

static void readword(unsigned char *buf)
{
  int d,e;
  unsigned char temp1024[1024];
  
  if(limit != 0) {
    word = 0;
    
    if(zero) {
      word = newressu_gen_limit(limit); // include zeroes
    } else if(limit >= 1) {
      while((word = newressu_gen_limit(limit)) == 0); // skip zeroes
    }
#ifdef DEBUG51
    if(type == 2)
      fprintf(stdout, "(%0*lx)", limitsize, word);
    else if(type == 8)
      fprintf(stdout, "(%0*lo)", limitsize, word);
    else if(type == 10)
      fprintf(stdout, "(%0*lu)", limitsize, word);
    else if(type == 16)
      fprintf(stdout, "(%0*lx)", limitsize, word);
    else {
      fprintf(stdout, "(%02lu)", word);
    }
#endif
	  
    out_word(sizeof(temp1024), temp1024, digits, word);
	  
    // fill leading zeroes
    
    buf[0] = '\0';
    utf8getcharactersemi(sizeof(character), character, 0, digits);
    for(d = size - utf8characters(temp1024); d > 0; d--) {
      strcat(buf, character);
    }
	  
    // rest of the number
	  
    strcat(buf, temp1024);
	  
  } else if(digits != NULL) {
	  
    buf[0] = '\0';
	  
#ifdef DEBUG51
    fprintf(stdout, "(");
#endif
    // fill whole word digit by digit
    for(d = 0; d < size; d++) {
      if(digits[0] == '0' && !zero)
	e = newressu_gen_limit(digitscount - 1) + 1;
      else
	e = newressu_gen_limit(digitscount);
      utf8getcharacter(sizeof(temp1024), temp1024, e, digits);
#ifdef DEBUG51
      fprintf(stdout,"%s", temp1024);
      if(charspaces == 1)
	fputc(' ', stdout);
#endif
      strcat(buf, temp1024);
    }
#ifdef DEBUG51
    fprintf(stdout, ")");
#endif
  }
}

//
// stdout printing routines
//

static int line_number_length()
{
  int c;
  out_word_10(sizeof(linenobuf), linenobuf, lines-1);
  c = strlen(linenobuf);
  if(c < 5)
    c = 5;
  return(c);
}

static void print_line_number()
{
  unsigned char linenobuf[32];
  
  if(cwords == 0 && slineno) {
    if(newressu_output) {
      fprintf(stdout,"\n");
      newressu_output = 0;
    }
    sprintf(linenobuf,"%0*llu", plinesdigits, plines);
    fprintf(stdout,"%s", linenobuf);
    fprintf(stdout," ");
  }
}

static void print_word(unsigned char *buf)
{
  int e;
  
  if(size != 0) {
    if(charspaces == 0) {
      fprintf(stdout, "%s", buf);
    } else {
      for(e = 0; e < size; e++) {
	unsigned char temp1024[1024];
	utf8getcharacter(sizeof(temp1024), temp1024, e, buf);
	fprintf(stdout, "%s", temp1024);
	fputc(' ', stdout);
      }
    }
  } else {
    fprintf(stdout, "%s", buf);
    if(charspaces == 1) {
      fputc(' ', stdout);
    }
  }
}

#ifdef SHA256

static void newressu_file_digest(char *filename,unsigned char *hash)
{
  int c;
  unsigned char buffer[1024];
  FILE *fp1;
  HashCtx ctx;
  
  HashInit(&ctx);
  if((fp1 = fopen(filename, "rb")) != NULL) {
    while((c = fread(buffer, 1, sizeof(buffer), fp1)) > 0) {
      //ressu_dump("buffer", c, buffer, 32); // first 32 bytes
      HashUpdate(&ctx, buffer, c);
    }
    fclose(fp1);
  }
  HashFinal(hash, &ctx);  
}

#endif

#define aDEBUG55 2
#define aDEBUG57 2

void digits_add_string(unsigned char **digits, char *str)
{
  int digitssize;

#ifdef DEBUG55
  fprintf(stdout,"\nolddigits %s", *digits);
  fprintf(stdout,"\nadddigits %s", str);
#endif
  digitssize = 0;
  if(*digits != NULL)
    digitssize += strlen(*digits);
  digitssize += strlen(str);

#ifdef DEBUG57
  fprintf(stdout,"digitssize:%d\n", digitssize);
  fflush(stdout);
#endif

  unsigned char *prevdigits = *digits;
  *digits = realloc(*digits, digitssize + 1);
  if(prevdigits == NULL)
    **digits = '\0';

  strcat(*digits, str);
#ifdef DEBUG55
  fprintf(stdout,"\nnewdigits %s", *digits);
  fprintf(stdout,"\n");
#endif
}

void digits_add_limits(unsigned char **digits, int start, int end)
{
  int digitssize;
  unsigned char buffer[32];
  long long ll;
  
#ifdef DEBUG55
  fprintf(stdout,"\nolddigits %s", *digits);
  fprintf(stdout,"\nadddigits start:%d, end:%d", start, end);
#endif
  digitssize = 0;
  if(*digits != NULL)
    digitssize += strlen(*digits);
  
  for(ll = start; ll <= end; ll++) {
    codetoutf8(buffer, ll);
    digitssize += strlen(buffer);
  }

#ifdef DEBUG57
  fprintf(stdout,"digitssize:%d\n", digitssize);
  fflush(stdout);
#endif
  
  unsigned char *prevdigits = *digits;
  *digits = realloc(*digits, digitssize + 1);
  if(prevdigits == NULL)
    **digits = '\0';

  for(ll = start; ll <= end; ll++) {
    codetoutf8(buffer, ll);
    strcat(*digits, buffer);
  }
#ifdef DEBUG55
  fprintf(stdout,"\nnewdigits %s", *digits);
  fprintf(stdout,"\n");
#endif
}

void strtolower(unsigned char *buf)
{
  while(*buf != '\0') {
    *buf = tolower(*buf);
    buf++;
  }
}

void strtoupper(unsigned char *buf)
{
  while(*buf != '\0') {
    *buf = toupper(*buf);
    buf++;
  }
}

double getseconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((double)tv.tv_sec + (double)tv.tv_usec / 1000000);
}

int newressu_getname(int length, unsigned char *name, unsigned char **p2)
{
  int len, ok = 0;
  unsigned char *n, *p;

  p = *p2;
  n = name;
  len = 0;
  
  while(ispunct(*p) || isblank(*p)) {
    p++;
  }

  while(*p != '\0' && !ispunct(*p) && !isblank(*p)) {
    if(len < length) {
      *n++ = *p;
      ok = 1;
    }
    p++;
    len++;
  }
  *n = '\0';
  
  *p2 = p;

  return(ok);
}

void newressu_base(int base2)
{
  base = base2;
  
  digits = malloc(base + 1);
  strncpy(digits, basedigits, base);
  if(uppercase == 1 && base <= 36) { // if lowercase only ([0-9] + [a-z], 10 + 26
    for(int c = 0; c < base; c++) { // to uppercase
      if(digits[c] >= 'a' && digits[c] <= 'z')
	digits[c] = digits[c] - 'a' + 'A';
      else if(digits[c] >= 'A' && digits[c] <= 'Z')
	digits[c] = digits[c] - 'A' + 'a';
    }
  }
  if(digitsext != NULL)
    free(digitsext);
  digitsext = digits;
  
  digits[base] = '\0';
}

#include <sys/ioctl.h> // for TIOCGWINSZ

#define aDEBUG50 2
#define aDEBUG71 2

void call_main(char *);

#define aCALL_MAIN 2

#ifdef CALL_MAIN

#define DEBUG99 2

int main2(int argc, char *argv[]);

void call_main(char *cmd)
{
  int size, round, count, chars;
  unsigned char *p, *q, *argmem,*params;
  char **argv;

  size = 0;

  for(round = 0; round < 2; round++) {
    count = 0;
    p = cmd;
    while(*p != '\0') {
      while(*p == ' ' || *p == '\t')
	p++;
      q = p;
      chars = 0;
      while(*p != ' ' &&  *p != '\t' && *p != '\0') {
	p++;
	chars++;
      }
      if(round == 0) // calculate size & alloc
	size += chars + 1 + sizeof(char *);
      else { // move parameters to arg area
	strncpy(params, q, chars);
	*(argv+count) = params;
	params += (chars+1);
      }
      count++;
    }
    if(round == 0) { // allocate
      size += sizeof(char *); // ending NULL
      argmem = malloc(size);
      argv = (char **)argmem;
      params = argmem + sizeof(char *) * (count+1);
    }
  }

  *(argv+count) = NULL; // ending NULL

#ifdef DEBUG99
  
  fprintf(stdout, "size:%d,", size);
  fprintf(stdout, " argmem:");
  for(int c = 0; c < size; c++) {
    if(c > 0 && c % 8 == 0)
      fprintf(stdout, "|");
    if(*(argmem+c) == '\\')
      fprintf(stdout, "\\\\");
    if(isprint(*(argmem + c)))
      fprintf(stdout, "%c", *(argmem + c));
    else
      fprintf(stdout, "\\%02x", *(argmem + c));
  }
  fprintf(stdout, "\n");

#endif // #ifdef DEBUG99

  main2(count, argv);
}

int main(int argc, char *argv[])
{
  int first;
  char buffer[1024];

  first = 1;
  buffer[0] = '\0';
  for(int c = 0; c < argc; c++) {
    if(!first)
      strcat(buffer, " ");
    strcat(buffer, argv[c]);
    first = 0;
  }
#ifdef DEBUG99
  fprintf(stdout,"main: cmd \"%s\"\n",buffer);
#endif
  
  call_main(buffer);
}

#endif // #ifdef CALL_MAIN

#ifdef CALL_MAIN

int main2(int argc, char *argv[])
{
#ifdef DEBUG99
  fprintf(stdout, "main2args:");  
  for(int c = 0; c < argc; c++) {
    fprintf(stdout, " %d:\"%s\"", c, argv[c]);
  }
  fprintf(stdout, "\n");
#endif // #ifdef DEBUG99

#else // #ifdef CALL_MAIN

static unsigned char programfiledigest[HashLen];

int main(int argc, char *argv[])
{
#endif // #ifdef CALL_MAIN
  
  int c, d, status = 0;

#define aDEBUG73 2

#ifdef DEBUG73
  
  int f;
  
  f = (ressu_useconds() / MILLION) % size;
  fprintf(stdout,"f1:%d\n",f);
  f = (ressu_useconds() / MILLION / 1024) % size;
  fprintf(stdout,"f2:%d\n",f);
  f = (ressu_useconds() / MILLION / 1024 / 1024) % size;
  fprintf(stdout,"f3:%d\n",f);
  f = (ressu_useconds() / MILLION / 1024 / 1024 / 1024) % size;
  fprintf(stdout,"f4:%d\n",f);
  f = (ressu_useconds() / MILLION / 1024 / 1024 / 1024 / 1024) % size;
  fprintf(stdout,"f5:%d\n",f);

#endif

#define aDEBUG2I 2
  
#ifdef DEBUG2I
  unsigned char urandom[1024];
  for(c = 0; c < 1024; c++) {
    fprintf(stdout,"%d", c);
    urandom_bytes(c, urandom);
    fprintf(stdout,"\n");
  }
#endif

#ifdef DEBUG2H

  for(int c = 0; c < RESSUT_BYTES; c++)
    count[c] = 0;

#endif

  procname = argv[0];

#define aDEBUG67A 2

#ifdef DEBUG67A
  unsigned long long big = 0xffffffffffffffff;
  fprintf(stdout,"0x%llx\n", big);
  fprintf(stdout,"0o%llo\n", big);
  fprintf(stdout,"0d%llu\n", big);
  fprintf(stdout,"0x%llx\n", big);
  for(int base = 2; base <= 64; base++) {
    fprintf(stdout,"base:%d, ", base);
    fprintfbase(stdout, big, base);
    fprintf(stdout,"\n");
  }
  fprintf(stdout,"number");
  for(int base = 2; base <= 64; base++) {
    fprintf(stdout," %d",base);
  }
  fprintf(stdout,"\n");
  for(unsigned long long ll = 0; ll < 1048576; ll++) {
  //for(unsigned long long ll = 4096; ll > 0; ll+=4096) {
  //for(unsigned long long ll = 1; ll != 0; ll *= 2) {
    fprintf(stdout,"%llu:", ll);
    for(int base = 2; base <= 64; base++) {
      fprintf(stdout," ");
      fprintfbase(stdout, ll, base);
    }
    fprintf(stdout,"\n");
  }
  fflush(stdout);
#endif

#define aDEBUG67B 2
  
#ifdef DEBUG67B

  unsigned char buffer4096[4096];
  unsigned char buffer[128];
  
  stream_open(0, stream_default_key);

  // fprintf(stderr,"read\n");
  stream_bytes(sizeof(buffer4096), buffer4096);
  //buffer4096[2048] = 1;

  // fprintf(stderr,"second read\n");
  
  for(int c = 1; c < sizeof(buffer); c++) {
    // fprintf(stdout,"%d", c);
    stream_open(0, stream_default_key);
    for(int d = 0; d < sizeof(buffer4096) - c + 1; d += c) {
      // fprintf(stdout," %d", d);
      stream_bytes(c, buffer);
      if(memcmp(buffer, buffer4096 + d, c)) {
	fprintf(stderr,"%s: compare mismatch (stream), c=%d, d=%d\n", procname, c, d);
	// exit(1);
      }
    }
    // fprintf(stdout,"\n");
  }
#endif

#define aDEBUG69
  
#ifdef DEBUG69
  stream_open(0, "⚀⚁⚂⚃⚄⚅"); // utf8  
  stream_open(0, "Hasta la vista, baby (Arnold Schwarzenegger, T2)"); // pass phrase
  stream_open(0, "abcdefghijklmnopqrstuvwxyz" // long password (key)
	      "abcdefghijklmnopqrstuvwxyz"
	      "abcdefghijklmnopqrstuvwxyz"
	      "abcdefghijklmnopqrstuvwxyz"
	      "abcdefghijklmnopqrstuvwxyz"); 
  stream_open(5, "\x00\x01\x02\x03\x04"); // binary string with length
#endif
  
#define aDEBUG74

#ifdef DEBUG74

  char *ds[] = { "A", "B", "T", "J", "X", "KH", "D", "R", "S", "SH",
		 "DH", "C", "G", "F", "Q", "K", "L", "M", "N", "W",
		 "H", "Y", "E", "O" }; // --som
  for(c= 0; c < sizeof(ds) / sizeof(ds[0]); c++)
    fprintf(stdout," `%s`",ds[c]);
  fprintf(stdout,"\n");

#endif

  unsigned char *flagchars[] =
    { "🇦", "🇧", "🇨", "🇩", "🇪", "🇫", "🇬", "🇭", "🇮", "🇯",
      "🇰", "🇱", "🇲", "🇳", "🇴", "🇵", "🇶", "🇷", "🇸", "🇹",
      "🇺", "🇻", "🇼", "🇽", "🇾", "🇿" };
  
#define DEBUG70

#ifdef DEBUG70

  for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
    unsigned char buffer20[20];
    unsigned char buffer128[128];
    sprintf(buffer128," %s", idsflags[c].flags);
    unsigned char *p = buffer128;
    if(idsflags[c].id[0] !=  '\0')
      continue;
    buffer20[0] = '\0';
    for(d = 0; *p != '\0'; d++) {
      if(isalpha(*p) == 0 &&
	 islower(*(p + 1)) != 0 &&
	 islower(*(p + 2)) != 0 &&
	 isalpha(*(p + 3)) == 0) {
	strcat(buffer20, flagchars[toupper(*(p + 1)) - 'A']);
	strcat(buffer20, flagchars[toupper(*(p + 2)) - 'A']);
      }
      p++;
    }
    fprintf(stdout,"  { \"%s\"", buffer20);
    fprintf(stdout,", \"%s: %s\" },\n", buffer20, idsflags[c].flags);
    fflush(stdout);
  }
  
#endif

#define aDEBUG68A // default is off

#ifdef DEBUG68A

  unsigned char *hindi = malloc(8192);
  digits_add_limits(&hindi,0x900,0x97f);   // Hindi (0900-097f)
  unsigned char *h;
  int first;

  //fprintf(stdout,"hindi1: %s\n", hindi);
  h = hindi;
  first = 1;
  while(*h != '\0') {
    if(!first)
      fprintf(stdout, " ");
    fputc(*h, stdout); // print first char
    if(*h > 0xbf) { // first char utf8
      h++;
      for(;;) { // print rest of the utf8 chars
	if(*h > 0xbf || // new utf8 character
	   *h < 0x80 || // ascii character
	   *h == '\0') // end of string
	  break;
	fputc(*h, stdout);
	h++;
      }
    }
    first = 0;
  }
  fprintf(stdout,"\n");
  free(hindi);
  
#endif

#define aDEBUG68B
#ifdef DEBUG68B
  fprintf(stdout,"hebrew: ");
  unsigned char *hebrew = malloc(8192);
  digits_add_limits(&hebrew, 0x590, 0x5ff);   //  (0590-05ff)
  // ֐֑֖֚֒֓֔֕֗֘֙־ֿ׀ׁׂ׃ׅׄ׆ׇ׈׉׊׋׌׍׎׏אבגדהוזחטיךכלםמןנסעףפץצקרשת׫׬׭׮ׯװױײ׳״׵׶׷׸׹׺׻׼׽׾׿
  fprintf(stdout,"%s\n", hebrew);
#endif

#define aDEBUG68C
#ifdef DEBUG68C
  fprintf(stdout,"phoenician: ");
  unsigned char *phoenician = malloc(8192);
  digits_add_limits(&phoenician, 0x10900, 0x1091f);   //  (10900-1091f)
  //phoenician: 𐤀𐤁𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊𐤋𐤌𐤍𐤎𐤏𐤐𐤑𐤒𐤓𐤔𐤕𐤖𐤗𐤘𐤙𐤚𐤛𐤜𐤝𐤞𐤟
  fprintf(stdout,"%s\n", phoenician);
#endif
  
  limit = 0;

#ifdef SHA256
  newressu_file_digest("/proc/self/exe", programfiledigest);
#endif
  
  newressu_clear();

  clockbytes = 0;
  for(d = 0; d < 1024; d++)
    periods[d] = 0;

#ifdef USE_TIMER
  int timer = 0;
  double timerstart;
#endif  

#define aDEBUG72 // default is on
		     
#ifdef DEBUG19	
  int flagint = 1;
#endif

  idsall = 1;
  newressu_toggleflag("ALL");
  int flagsinit = 0;
		     
  //
  // look thru command line parameters
  // for flags option
  //

  int flagflags = 0;
  for(c = 1; c < argc; c++) {
    if(!strcmp("--flags", argv[c])) { // not ready
      flagflags = 1;
    }
  }

  //
  // look thru command line parameters
  //

  for(c = 1; c < argc; c++) {

    int ok = 1;

    if(!strncmp("-", argv[c], 1)) {

      if(!strcmp("--help", argv[c]) ||
	 !strcmp("-?", argv[c])) {
	help = 1;
	
      } else if(!strcmp("--quiet", argv[c])) {
	quiet = !quiet;

      } else if(!strcmp("--stats", argv[c]) ||
	!strcmp("--stat", argv[c])) {
	stats = !stats;

      } else if(!strcmp("--digits", argv[c])) {
	flagprintdigits = !flagprintdigits;

      } else if(!strcmp("--columns", argv[c])) {
	columns = !columns; // print column numbers
	
      } else if(!strncmp("--space", argv[c], 7)) {
	if(isdigit(*(argv[c] + 7))) {
	  sspace = atoi(argv[c] + 7);
	} else if(c + 1 < argc && isdigit(*(argv[c + 1]))) {
	  sspace = atoi(argv[c + 1]);
	  c++;
	} else {
	  sspace = !sspace;
	}

      } else if(!strncmp("--newline", argv[c], 9)) {
	if(*(argv[c] + 9) != '\0' && atoi(argv[c] + 9) > 0) {
	  snewline = atoi(argv[c] + 9);
	} else if(c + 1 < argc && atoi(argv[c + 1]) > 0) {
	  snewline = atoi(argv[c + 1]);
	  c++;
	}

      } else if(!strcmp("--sample", argv[c])) {
	sample = !sample;
	
      } else if(!strcmp("--dieharder", argv[c])) {
	dieharder = !dieharder;
	
      } else if(!strcmp("--purge", argv[c])) {
	purge = !purge;
	purge_set = 1;
	
      } else if(!strcmp("--save", argv[c])) {
	purge = 1;
	purge_set = 1;
	
#ifdef DEBUG59
      } else if(!strcmp("--utf8", argv[c])) {
	utf8 = !utf8;
	
#endif
      } else if(!strncmp("--filesize", argv[c], 10)) {
	if(*(argv[c] + 10) != '\0') {
	  filesize_str = argv[c] + 10;
	  filesize = getlonglong(filesize_str);
	} else if(c + 1 < argc) {
	  filesize_str = argv[c + 1];
	  filesize = getlonglong(filesize_str);
	  c++;
	}
	filesize_set = 1;

      } else if(!strncmp("--blocksize", argv[c], 11)) {
	if(*(argv[c] + 11) != '\0') {
	  blocksize_str = argv[c] + 10;
	  blocksize = getlonglong(blocksize_str);
	} else if(c + 1 < argc) {
	  blocksize_str = argv[c + 1];
	  blocksize = getlonglong(blocksize_str);
	  c++;
	}
	blocksize_set = 1;
	
      } else if(!strncmp("--blocks", argv[c], 8)) {
	if(*(argv[c] + 8) != '\0') {
	  blocks_str = argv[c] + 10;
	  blocks = getlonglong(blocks_str);
	} else if(c + 1 < argc) {
	  blocks_str = argv[c + 1];
	  blocks = getlonglong(blocks_str);
	  c++;
	}
	blocks_set = 1;

      } else if(!strcmp("--copyright", argv[c]) ||
	 !strcmp("--version", argv[c])) {
	newressu_version();
#ifdef SHA256
	fprintf(stderr,"\nsha256(");
	for(int c = 0; c < HashLen; c++) {
	  fprintf(stderr, "%02x", programfiledigest[c]);
	}
#endif
	fprintf(stderr, ")\n\n");
	help = 0;
	exit(1);
	
      } else if(!strcmp("--webversion", argv[c])) {
	fprintf(stderr, "%s", programname); // touch these outside MAIN
	fprintf(stderr,", sha256(");
	for(int c = 0; c < HashLen; c++) {
	  fprintf(stderr, "%02x", programfiledigest[c]);
	}
	fprintf(stderr,")\n");
	exit(0);

      } else if(!strcmp("--lineno", argv[c])) {
	slineno = !slineno; // print line number
	
      } else if(!strcmp("--crlf", argv[c])) {
	scrlf = !scrlf;
	slineno = 0;

#ifdef DEBUG19	
      } else if(!strcmp("--int", argv[c])) {
	flagint = !flagint;

#endif
      } else if(!strcmp("--rand", argv[c])) {
	digits = "0123456789";
	sspace = 2;
	snewline = 5;
	slineno = 1; // print line number
	words = 10;
	chars = 0;
	limit = 100000;
	//size = 5;
	//lines = 20000;
	
      } else if(!strcmp("--zero", argv[c])) {
	zero = !zero;

      } else if(!strcmp("--sort", argv[c])) {
	sort = !sort;
	if(sspace == 0)
	  sspace = 1;
		
      } else if(!strcmp("--unique", argv[c])) {
	unique =! unique;
	if(sspace == 0)
	  sspace = 1;
		
      } else if(!strcmp("--lotto", argv[c])) {
	sort = !sort;
	if(sspace == 0)
	  sspace = 1;
	//sort = 1;
	//unique = 1;

      } else if(!strncmp("--lim", argv[c], 5)) { // limit of word
	if(*(argv[c] + 5) != '\0') {
	  in_word(&limit, digits, argv[c] + 5);
	} else if(c+1 < argc) {
	  in_word(&limit, digits, argv[c + 1]);
	  c++;
	}
	//fprintf(stdout,"limit:%lu, %ld bytes\n", limit, sizeof(limit));
	if(sspace < 1 ) // 23.6.2021
	  sspace = 1;

      } else if(!strncmp("--size", argv[c], 6)) { // size of word
	if(isdigit(*(argv[c] + 6))) {
	  size = atoi(argv[c] + 6);
	} else if(c + 1 < argc) {
	  size = atoi(argv[c + 1]);
	  c++;
	}
	limit = 0; // 23.6.2021

      } else if(!strncmp("-s", argv[c], 2)) { // size of word
	if(isdigit(*(argv[c] + 2))) {
	  size = atoi(argv[c] + 2);
	} else if(c + 1 < argc) {
	  size = atoi(argv[c + 1]);
	  c++;
	}
	limit = 0; // 23.6.2021

      } else if(!strncmp("--bits", argv[c], 6)) {
	if(isdigit(*(argv[c] + 6))) {
	  ressut_bits1_needed = atoi(argv[c] + 6);
	} else if(c + 1 < argc) {
	  ressut_bits1_needed = atoi(argv[c + 1]);
	  c++;
	}	

      } else if(!strncmp("--bytes", argv[c], 7)) {
	if(isdigit(*(argv[c] + 7))) {
	  ressut_bytes = atoi(argv[c] + 7);
	} else if(c + 1 < argc) {
	  ressut_bytes = atoi(argv[c + 1]);
	  c++;
	}	

      } else if(!strncmp("--words", argv[c], 7)) { // words per line
	if(isdigit(*(argv[c] + 7))) {
	  words = atoi(argv[c] + 7);
	} else if(c + 1 < argc) {
	  words = atoi(argv[c + 1]);
	  c++;
	}
	if(words < 1)
	  words = 1;
	chars = 0;
	screen = 0;
	
      } else if(!strncmp("-w", argv[c], 2)) { // words per line
	if(isdigit(*(argv[c] + 2))) {
	  words = atoi(argv[c] + 2);
	} else if(c + 1 < argc) {
	  words = atoi(argv[c + 1]);
	  c++;
	}
	if(words < 1)
	  words = 1;
	chars = 0;
	screen = 0;
	
      } else if(!strcmp("-c*", argv[c])) {
	struct winsize w;
	ioctl(0, TIOCGWINSZ, &w);
	chars = w.ws_col;
	words = 0;

      } else if(!strcmp("-l*", argv[c])) {
	struct winsize w;
	ioctl(0, TIOCGWINSZ, &w);
	lines = w.ws_row-1;

      } else if(!strcmp("--chars*", argv[c])) {
	struct winsize w;
	ioctl(0, TIOCGWINSZ, &w);
	chars = w.ws_col;
	words = 0;

      } else if(!strcmp("--lines*", argv[c])) {
	struct winsize w;
	ioctl(0, TIOCGWINSZ, &w);
	lines = w.ws_row-1;

      } else if(!strncmp("--screen", argv[c],8)) { // screenful
	struct winsize w;
	ioctl(0, TIOCGWINSZ, &w);
	chars = w.ws_col;
	lines = w.ws_row-1;
	words = 0;
	screen = 1;
	
      } else if(!strncmp("--chars", argv[c], 7)) {  // characters per line
	if(isdigit(*(argv[c] + 7))) {
	  chars = atoi(argv[c] + 7);
	} else if(c + 1 < argc) {
	  chars = atoi(argv[c + 1]);
	  c++;
	}
	if(chars < 1)
	  chars = 72;
	words = 0;
	screen = 0;
	
      } else if(!strncmp("-c", argv[c], 2)) {  // characters per line
	if(isdigit(*(argv[c] + 2))) {
	  chars = atoi(argv[c] + 2);
	} else if(c + 1 < argc) {
	  chars = atoi(argv[c + 1]);
	  c++;
	}
	if(chars < 1)
	  chars = 72;
	words = 0;
	screen = 0;
	
      } else if(!strncmp("--lines",argv[c], 7)) { // lines
	if(isdigit(*(argv[c] + 7))) {
	  lines = atoll(argv[c] + 7);
	} else if(c + 1 < argc) {
	  lines = atoll(argv[c + 1]);
	  c++;
	}
	screen = 0;
	
      } else if(!strncmp("-l",argv[c], 2)) { // lines
	if(isdigit(*(argv[c] + 2))) {
	  lines = atoll(argv[c] + 2);
	} else if(c + 1 < argc) {
	  lines = atoll(argv[c + 1]);
	  c++;
	}
	screen = 0;
	
      } else if(!strcmp("--otp1", argv[c]) || // see: one time pad
		!strcmp("--otp5n", argv[c]) || // digits length 5
		!strcmp("--onetimepad1", argv[c])) {		
	digits = "0123456789";
	sspace = 1;
	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;
	
      } else if(!strcmp("--otp2", argv[c]) || // uppercase alpha length 5
		!strcmp("--otp5a", argv[c]) ||		
		!strcmp("--onetimepad2", argv[c]) ||
		!strcmp("--diana", argv[c]) ) { // see: diana cipher, diana table
	digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	sspace = 1;
	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;
	
      } else if(!strcmp("--otp3", argv[c]) || // uppercase alpha length 4
		!strcmp("--otp4a", argv[c]) ||		
		!strcmp("--onetimepad3", argv[c])) {
	digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	sspace = 1;
	charspaces = 0;
	charwidth = 1;
	size = 4;
	type = 0;

      } else if(!strncmp("--base", argv[c], 6)) {

	if(isdigit(*(argv[c] + 6))) {
	  newressu_base(atoi(argv[c] + 6));
	} else if(c + 1 < argc) {
	  newressu_base(atoi(argv[c + 1]));
	  c++;
	}
	if(base < 2 || base > 64) {
	  fprintf(stderr,"%s: base must be from 2 to 64 (%s)\n", procname, argv[c]);
	  exit(2);
	}
      } else if(!strncmp("--BASE", argv[c], 6)) {

	if(isdigit(*(argv[c] + 6))) {
	  uppercase = 1;
	  newressu_base(atoi(argv[c] + 6));
	} else if(c + 1 < argc) {
	  uppercase = 1;
	  newressu_base(atoi(argv[c + 1]));
	  c++;
	}
	if(base < 2 || base > 64) {
	  fprintf(stderr,"%s: base must be from 2 to 64 (%s)\n", procname, argv[c]);
	  exit(2);
	}
	
      } else if(!strcmp("-b", argv[c]) ||
		!strcmp("--bin", argv[c]) ||
		!strcmp("--1bit", argv[c]) ||
		!strcmp("--1bits", argv[c])) {

	newressu_base(2);
	
      } else if(!strcmp("--2bits", argv[c])) {

	newressu_base(4);

      } else if(!strcmp("-o", argv[c]) ||
		!strcmp("--oct", argv[c]) ||
		!strcmp("--3bits", argv[c]) ) {

	newressu_base(8);

      } else if(!strcmp("-d", argv[c]) ||
		!strcmp("--dec", argv[c])) {

	newressu_base(10);

      } else if(!strcmp("-x", argv[c]) ||
		!strcmp("--hex", argv[c]) ||
		!strcmp("--4bits", argv[c])) {

	newressu_base(16);

      } else if(!strcmp("-X", argv[c]) ||
		!strcmp("--HEX", argv[c]) ||
		!strcmp("--4BITS", argv[c])) {

	newressu_base(16);
	uppercase = 1;

      } else if(!strcmp("-5", argv[c]) ||
		!strcmp("--5bits", argv[c])) {

	newressu_base(32);
	base = 32;
	
      } else if(!strcmp("--5BITS", argv[c])) {

	newressu_base(32);
	uppercase = 1;
	
      } else if(!strcmp("-2", argv[c]) ||
		!strcmp("--6bits", argv[c])) {

	newressu_base(64);
	
      } else if(!strcmp("-1", argv[c])) {
	digits =
	  "0123456789" \
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
	  "abcdefghijklmnopqrstuvwxyz";

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;

      } else if(!strcmp("--numeric", argv[c]) ||
		!strcmp("-11", argv[c])) {
	digits =
	  "0123456789";

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 10;

      } else if(// !strcmp("--ALPHA", argv[c]) ||
		!strcmp("--LATIN", argv[c]) ||
		!strcmp("-12", argv[c]) ) {
	digits =
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	charspaces = 0;
	charwidth = 1;
	size = 5;

      } else if( //!strcmp("--alpha", argv[c]) ||
		!strcmp("--latin", argv[c]) ||
		!strcmp("-13", argv[c])) {
	digits =
	  "abcdefghijklmnopqrstuvwxyz";

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;

      } else if(!strcmp("-13v1", argv[c])) {
	digits =
	  "abcdefghijklmnopqrstuvwxyz" \
	  "aeiouy"; // extra vowels

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;

      } else if(!strcmp("-13v2", argv[c])) {
	digits =
	  "abcdefghijklmnopqrstuvwxyz"
	  "aeiouy" // extra vowels
	  "aeiouy"; // extra vowels

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;

      } else if(!strcmp("-13v3", argv[c])) {
	digits =
	  "abcdefghijklmnopqrstuvwxyz"
	  "aeiouy" // extra vowels
	  "aeiouy" // extra vowels
	  "aeiouy"; // extra vowels

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;

      } else if(!strcmp("-13v4", argv[c])) {
	digits =
	  "abcdefghijklmnopqrstuvwxyz"
	  "aeiouy" // extra vowels
	  "aeiouy" // extra vowels
	  "aeiouy" // extra vowels
	  "aeiouy"; // extra vowels

	charspaces = 0;
	charwidth = 1;
	size = 5;
	type = 0;
 
      } else if(!strcmp("-3", argv[c])) { // 9.5.2021 JariK
	digits =
	  "!\"#$%&'()*+,-./0123456789:;<=>?@" \
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
	  "abcdefghijklmnopqrstuvwxyz{|}~";

	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("-9", argv[c])) {
	digits =
	  "0123456789" \
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
	  "abcdefghijklmnopqrstuvwxyz";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--dnk", argv[c]) || // Danish alphabet
		!strcmp("--nor", argv[c])) { // Norwegian alphabet
	digits =
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" \
	  "abcdefghijklmnopqrstuvwxyzæøå";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--fin", argv[c]) || // Finnish alphabet
		!strcmp("--swe", argv[c])) { // Swedish alphabet
	digits =
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ" \
	  "abcdefghijklmnopqrstuvwxyzåäö";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--rus", argv[c])) { // Russian alphabet
	digits =
	  "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" \
	  "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--est", argv[c])) { // Estonian alphabet

	digits =
	  "ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY" \
	  "abcdefghijklmnopqrsšzžtuvwõäöüxy";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;
  
      } else if(!strcmp("--ltu", argv[c])) { // Lithuanian alphabet
	digits =
	  "AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ" \
	  "aąbcčdeęėfghiįyjklmnoprsštuųūvzž";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--lva", argv[c])) { // Latvian alphabet
	digits =
	  "AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ" \
	  "aābcčdeēfgģhiījkķlļmnņoprsštuūvzž";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--fra", argv[c]) // French alphabet
		||!strcmp("--gbr", argv[c]) // Great Britain alphabet
		||!strcmp("--usa", argv[c]) // United States alphabet
		||!strcmp("--ita", argv[c]) // Italian alphabet
		||!strcmp("--eng", argv[c]) // English alphabet
		) {
	digits =
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
	  "abcdefghijklmnopqrstuvwxyz";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--deu", argv[c])) { // Deutsch alphabet
	digits =
	  "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" \
	  "abcdefghijklmnopqrstuvwxyzäöüß";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--grc", argv[c])) { // Greek alphabet
	digits =
	  "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ" \
	  "αβγδεζηθικλμνξοπρστυφχψω";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;
	
      } else if(!strcmp("--jp", argv[c])) { // all Japanese alphabets

	digits = NULL;
	digits_add_string(&digits,
	    "ぁあぃいぅうぇえぉおかがきぎく"
	  "ぐけげこごさざしじすずせぜそぞた"
	  "だちぢっつづてでとどなにぬねのは"
	  "ばぱひびぴふぶぷへべぺほぼぽまみ"
	  "むめもゃやゅゆょよらりるれろゎわ"
	  "ゐゑをんゔゕゖ");
	digits_add_string(&digits,
	  "゠ァアィイゥウェエォオカガキギク"
	  "グケゲコゴサザシジスズセゼソゾタ"
	  "ダチヂッツヅテデトドナニヌネノハ"
	  "バパヒビピフブプヘベペホボポマミ"
	  "ムメモャヤュユョヨラリルレロヮワ"
	  "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ");
	digits_add_limits(&digits, 0x4e00, 0x9fef);

	digitsext = digits;
	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;

      } else if(!strcmp("--jp1", argv[c]) // Japanese hiragana alphabet
	     || !strcmp("--hir", argv[c])) {
	digits =
	    "ぁあぃいぅうぇえぉおかがきぎく"
	  "ぐけげこごさざしじすずせぜそぞた"
	  "だちぢっつづてでとどなにぬねのは"
	  "ばぱひびぴふぶぷへべぺほぼぽまみ"
	  "むめもゃやゅゆょよらりるれろゎわ"
	  "ゐゑをんゔゕゖ";

	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;

      } else if(!strcmp("--jp2", argv[c]) // Japanese katakana alphabet
	     || !strcmp("--kat", argv[c])) {
	digits =
	  "゠ァアィイゥウェエォオカガキギク"
	  "グケゲコゴサザシジスズセゼソゾタ"
	  "ダチヂッツヅテデトドナニヌネノハ"
	  "バパヒビピフブプヘベペホボポマミ"
	  "ムメモャヤュユョヨラリルレロヮワ"
	  "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ";

	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;

      } else if(!strcmp("--cn", argv[c]) // Chinese alphabet 
	     || !strcmp("--jp3", argv[c]) // Japanese kanji alphabet
	     || !strcmp("--kan", argv[c])) { // Japanese kanji alphabet

	digits = NULL;
	digits_add_limits(&digits, 0x4e00, 0x9fef);

	digitsext = digits;
	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;
	
      } else if(!strcmp("--kor", argv[c])) { // Korean alphabet 

	digits = NULL;
	digits_add_limits(&digits,0xac00,0xd7a3);   // Hangul Syllables (AC00–D7A3)
	//digits_add_limits(&digits,0x1100,0x11ff); // Hangul Jamo (1100–11FF)
	//digits_add_limits(&digits,0x3130,0x318f); // Hangul Compatibility Jamo (3130–318F)
	//digits_add_limits(&digits,0xa960,0xa97f); // Hangul Jamo Extended-A (A960–A97F)
	//digits_add_limits(&digits,0xd7b0,0xd7ff); //Hangul Jamo Extended-B (D7B0–D7FF)

	digitsext = digits;
	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;

      } else if(!strcmp("--ind", argv[c]) // not ready
	     || !strcmp("--hin", argv[c])) { // Hindi alphabet
	//unsigned char *signs = "ऀँंःऺऻ़ऽािीुूृॄॅॆेैॉॊोौ्ॎॏॕॖॗॢॣ॒॑॓॔";
	digits =
	  "ऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढण"
	  "तथदधनऩपफबभमयरऱलळऴवशषसहऽॐक़ख़ग़ज़ड़"
	  "ढ़फ़य़ॠॡ।॥०१२३४५६७८९॰ॱॲॳॴॵॶॷॸॹॺॻॼॽॾ"
	  "ॿ"; // 97 characters

	//digits_add_limits(&digits,0x900,0x97f);   // Hindi (0900-097f)

	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--heb", argv[c])) { // hebrew

	// ֐֑֖֚֒֓֔֕֗֘֙־ֿ׀ׁׂ׃ׅׄ׆ׇ׈׉׊׋׌׍׎׏אבגדהוזחטיךכלםמןנסעףפץצקרשת׫׬׭׮ׯװױײ׳״׵׶׷׸׹׺׻׼׽׾׿
	
	digits = "אבגדהוזחטיךכלםמןנסעףפץצקרשת";

	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--pho", argv[c])) { // phoenician alphabet, (fi "foinikialaiset aakkoset")

	//phoenician: 𐤀𐤁𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊𐤋𐤌𐤍𐤎𐤏𐤐𐤑𐤒𐤓𐤔𐤕𐤖𐤗𐤘𐤙𐤚𐤛𐤜𐤝𐤞𐤟
	digits = "𐤀𐤁𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊𐤋𐤌𐤍𐤎𐤏𐤐𐤑𐤒𐤓𐤔𐤕𐤖𐤗𐤘𐤙𐤚𐤛";

	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--som", argv[c]) ||
		!strcmp("--SOM", argv[c]) ||
		!strcmp("--SO", argv[c])) { // Somalia alphabet

#define aNEWSOM 2
	
#ifdef NEWSOM
	digits = NULL;
	// 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
	digits_add_string(&digits, "A;");
	digits_add_string(&digits, "B;");
	digits_add_string(&digits, "T;");
	digits_add_string(&digits, "J;");
	digits_add_string(&digits, "X;");
	digits_add_string(&digits, "KH;");
	digits_add_string(&digits, "D;");
	digits_add_string(&digits, "R;");
	digits_add_string(&digits, "S;");
	digits_add_string(&digits, "SH;");
	digits_add_string(&digits, "DH;");
	digits_add_string(&digits, "C;");
	digits_add_string(&digits, "G;");
	digits_add_string(&digits, "F;");
	digits_add_string(&digits, "Q;");
	digits_add_string(&digits, "K;");
	digits_add_string(&digits, "L;");
	digits_add_string(&digits, "M;");
	digits_add_string(&digits, "N;");
	digits_add_string(&digits, "W;");
	digits_add_string(&digits, "H;");
	digits_add_string(&digits, "Y;");
	digits_add_string(&digits, "E;");
	digits_add_string(&digits, "O;");

	flagdigits = 2; // semicolon separated (flags)
	
#else
	// missing KH SH DH
	digits = "ABTJXDRSCGFQKLMNWHYEO";
#endif
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--braille", argv[c])) { // Braille alphabet
	digits = // 0x2800 - 0x2900
	  "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
	  "⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿"
	  "⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿"
	  "⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿";
	charspaces = 0;
	charwidth = 1;
	size = 8;
	type = 0;

      } else if(!strcmp("--got", argv[c])) { // Gothic alphabet
        digits=
          "𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷𐌸𐌹𐌺𐌻𐌼𐌽𐌾𐌿"
          "𐍀𐍁𐍂𐍃𐍄𐍅𐍆𐍇𐍈𐍉𐍊";

      } else if(!strcmp("---champagne", argv[c])) { // Party
        digits = "🍾🥂🥂🥂🥂"; // 🥤🥤🥤🥤🥤🥤🥤🥤"; // 
	charspaces = 0;
	charwidth = 2;
        size = 8;
	type = 0;

      } else if(!strcmp("--cards", argv[c])) {
	digits=
	  "🂡🂢🂣🂤🂥🂦🂧🂨🂩🂪🂫🂭🂮"
	  "🂱🂲🂳🂴🂵🂶🂷🂸🂹🂺🂻🂽🂾"
	  "🃁🃂🃃🃄🃅🃆🃇🃈🃉🃊🃋🃍🃎"
	  "🃑🃒🃓🃔🃕🃖🃗🃘🃙🃚🃛🃝🃞";

	charspaces = 1;
	charwidth = 2;
	size = 5;
	type = 0;

      } else if(!strcmp("--cardsuits", argv[c])) {
	digits=
	  "♠♡♢♣♤♥♦♧";

	charspaces = 1;
	charwidth = 2;
	size = 5;
	type = 0;

      } else if(!strcmp("--chessmen", argv[c])) {
	digits=
	  "♔♕♖♗♘♙♚♛♜♝♞♟";

	charspaces = 1;
	charwidth = 2;
	size = 5;
	type = 0;

      } else if(!strcmp("--dice", argv[c])) {
	digits=
	  "⚀⚁⚂⚃⚄⚅";

	charspaces = 1;
	charwidth = 2;
	size = 5;
	type = 0;

      } else if(!strcmp("--mahjong", argv[c])) {
	digits= // removed 🀄 & 🀫
	  "🀀🀁🀂🀃🀅🀆" \
	  "🀇🀈🀉🀊🀋🀌🀍🀎🀏" \
	  "🀐🀑🀒🀓🀔🀕🀖🀗🀘" \
	  "🀙🀚🀛🀜🀝🀞🀟🀠🀡" \
	  "🀢🀣🀤🀥🀦🀧🀨🀩🀪";

	charspaces = 1;
	charwidth = 2;
	size = 5;
	type = 0;

      } else if(!strcmp("--dna", argv[c])) {
	digits=
	  "acgt";
	charspaces = 0;
	charwidth = 1;
	size = 4;
	type = 0;
	
      } else if(!strcmp("--DNA", argv[c])) {
	digits=
	  "ACGT";

	charspaces = 0;
	charwidth = 1;
	size = 4;
	type = 0;
	
      } else if(!strcmp("--pattern1", argv[c])) {
	digits=
	  "▌▙▄";

	charspaces = 0;
	charwidth = 1;
	size = 1;
	type = 0;

      } else if(!strcmp("--pattern2", argv[c])) {
	digits=
	  "◜◝◞◟";

	charspaces = 0;
	charwidth = 1;
	size = 1;
	type = 0;

      } else if(!strcmp("--pattern3", argv[c])) {
	digits=
	  "\\/";

	charspaces = 0;
	charwidth = 1;
	size = 1;
	type = 0;

      } else if(!strcmp("--pattern4", argv[c])) {
	digits=
	  "◸◹◺◿";

	charspaces = 1;
	charwidth = 2;
	size = 1;
	type = 0;

      } else if(!strcmp("--pattern5", argv[c])) {
	digits=
	  "▧▨";

	charspaces = 1;
	charwidth = 2;
	size = 1;
	type = 0;

      } else if(!strcmp("--alnum", argv[c]) || // 9.5.2021 JariK
	        !strcmp("--alpha", argv[c]) ||
	        !strcmp("--digit", argv[c]) ||
	        !strcmp("--graph", argv[c]) ||
	        !strcmp("--lower", argv[c]) ||
	        !strcmp("--print", argv[c]) ||
	        !strcmp("--punct", argv[c]) ||
	        !strcmp("--upper", argv[c]) ||
		!strcmp("--xdigit", argv[c])) {
	unsigned char *p = digitstemp;
	for(d = 0; d < 256; d++) {
	  if((!strcmp("--alnum", argv[c]) && isalnum(d)) ||
	     (!strcmp("--alpha", argv[c]) && isalpha(d)) ||
	     (!strcmp("--digit", argv[c]) && isdigit(d)) ||
	     (!strcmp("--graph", argv[c]) && isgraph(d)) ||
	     (!strcmp("--lower", argv[c]) && islower(d)) ||
	     (!strcmp("--print", argv[c]) && isprint(d)) ||
	     (!strcmp("--punct", argv[c]) && ispunct(d)) ||
	     (!strcmp("--upper", argv[c]) && isupper(d)) ||
	     (!strcmp("--xdigit", argv[c]) && isxdigit(d))) {
	    *p++ = d;
	  }
	}
	*p = '\0';
	digits = digitstemp;
	size = 5;
	type = 0;

      } else if(!strncmp("-i", argv[c], 2)) {
	digits = NULL;
	if(*(argv[c] + 2) != '\0') {
	  digits = argv[c] + 2;
	} else if(c + 1 < argc) {
	  digits = argv[c + 1];
	  c++;
	}
	if(digits == NULL || utf8characters(digits) < 2) {
	  fprintf(stderr,"%s: not enough digits \"%s\"\n", procname, argv[c]);
	}
	size = 1;

#ifdef USE_TIMER
      } else if(!strcmp("--timer", argv[c])) {
	timer = 1;

#endif
      } else if(!strcmp("--clockstream", argv[c])) { // clockstream
	input = INPUT_CLOCK;
	input_str = argv[c] + 2;
	
      } else if(!strcmp("--test", argv[c])) { // test generator
	input = INPUT_TEST;
	input_str = argv[c] + 2;
	
      } else if(!strcmp("--ressu", argv[c])) {
	input = INPUT_RESSU;
	input_str = argv[c] + 2;
	
      } else if(!strcmp("--pseudoressu", argv[c])) {
	input = INPUT_PSEUDORESSU;
	input_str = argv[c] + 2;

      } else if(!strcmp("--ressutwist", argv[c]) // JariK 2023
		|| !strcmp("--ressuwtwist", argv[c])
	        || !strcmp("--twist", argv[c]) ) {
	input = INPUT_RESSUTWIST;
	input_str = argv[c] + 2;

      } else if(!strcmp("--pseudorandom", argv[c])) {
	input = INPUT_PSEUDORANDOM;
	input_str = argv[c] + 2;

      } else if(!strcmp("--ressu2", argv[c])) {
	input = INPUT_RESSU2;
	input_str = argv[c] + 2;

      } else if(!strcmp("--pseudoressu2", argv[c])) {
	input = INPUT_PSEUDORESSU2;
	input_str = argv[c] + 2;

      } else if(!strcmp("--ressu2twist", argv[c]) // JariK 2023
		|| !strcmp("--ressu2wtwist", argv[c])) {
	input = INPUT_RESSU2TWIST;
	input_str = argv[c] + 2;

      } else if(!strcmp("--ressu3", argv[c])) {
	input = INPUT_RESSU3;
	input_str = argv[c] + 2;

      } else if(!strcmp("--fast", argv[c])
		|| !strcmp("--fastressu", argv[c]) ) {
	input = INPUT_FASTRESSU;
	input_str = argv[c] + 2;

      } else if(!strcmp("--single", argv[c])
		|| !strcmp("--singleressu", argv[c]) ) {
	input = INPUT_SINGLERESSU;
	input_str = argv[c] + 2;

      } else if(!strcmp("--stream", argv[c])) {
	input = INPUT_STREAM;
	input_str = argv[c] + 2;
	
      } else if(!strncmp("--name", argv[c], 6)) {
	if(*(argv[c] + 6) != '\0') {
	  input_str = argv[c] + 6;
	} else if(c + 1 < argc) {
	  input_str = argv[c + 1];
	}	

      } else if(!strncmp("--key", argv[c], 5)) {
	key = NULL;
	if(*(argv[c] + 5) != '\0') {
	  key = argv[c] + 5;
	} else if(c + 1 < argc) {
	  key = argv[c + 1];
	  c++;
	}
	if(key == NULL || utf8characters(key) < 1) {
	  fprintf(stderr,"%s: not enough key characters \"%s\"\n", procname, argv[c]);
	  exit(1);
	}
	//size = 1;

      } else if(!strncmp("--fixedclock", argv[c], 12)) {
	if(*(argv[c] + 12) != '\0' && atoi(argv[c] + 12) > 1) {
	  fixedclockchainlength = atoi(argv[c] + 12);
	  fixedclock = 1;
	} else if(c + 1 < argc && atoi(argv[c + 1]) > 1) {
	  fixedclockchainlength = atoi(argv[c + 1]);
	  fixedclock = 1;
	  c++;
	} else {
	  fixedclock = !fixedclock;
	}

	if(fixedclockchainlength < 5 ||
	   fixedclockchainlength > 255)
	  fixedclockchainlength = FIXEDCLOCKCHAINLENGTH;

      } else if(!strncmp("--depth", argv[c], 7)) {
	if(isdigit(*(argv[c] + 7))) {
	  depth = atoi(argv[c] + 7);

	} else if(c + 1 < argc && isdigit(*(argv[c + 1]))) {
	  depth = atoi(argv[c + 1]);
	  c++;
	  
	} else {
	  depth = MAX_DEPTH;
	}

	if(depth < 0 || depth > MAX_DEPTH) {
	  fprintf(stderr,"%s: --depth must be between 0 and %d(MAX_DEPTH)\n",
		  procname, MAX_DEPTH);
	  exit(2);
	}

	fprintf(stderr,"depth:%d\n", depth);

      } else if(!strcmp("--copyreverse", argv[c])) {
	copyreverse = !copyreverse;
	
      } else if(!strcmp("--verbose", argv[c])) {
	verbose = !verbose;
	
      } else if(!strcmp("--statline", argv[c])) {
	print_statline = !print_statline;

#ifdef FORT
      } else if(!strcmp("--fort", argv[c])) {
	input = INPUT_FORT;
	input_str = argv[c] + 2;

      } else if(!strcmp("--fortxor", argv[c])) {
	input = INPUT_FORTXOR;
	input_str = argv[c] + 2;

      } else if(!strcmp("--fortverbose", argv[c])) {
	verbose = !verbose;

      } else if(!strcmp("--fortuseweb", argv[c])) {
	fort_use_web = !fort_use_web;
	
#endif
#ifdef USE_RDRAND
      } else if(!strcmp("--rdrand", argv[c])) {
	input = INPUT_RDRAND;
	input_str = argv[c] + 2;

#endif
#ifdef USE_RDSEED
      } else if(!strcmp("--rdseed", argv[c])) {
	input = INPUT_RDSEED;
	input_str = argv[c] + 2;

#endif
      } else if(!strcmp("--urandom", argv[c])) {
	input = INPUT_URANDOM;
	input_str = argv[c] + 2;

#ifdef USE_RANDOM
      } else if(!strcmp("--random", argv[c])) {
	input = INPUT_RANDOM;
	input_str = argv[c] + 2;

#endif
      } else if(!strcmp("--dummy", argv[c])) {
	input = INPUT_DUMMY;
	input_str = argv[c] + 2;

      } else if(!strcmp("--flags", argv[c])) { // not ready

	charspaces = 0;
	charwidth = 2;
	size = 8;
	type = 0;
	flagdigits = 1; // semicolon separated (flags)
	
	// code after command line parameter loop
	
      } else if(!strcmp("--all", argv[c])) { // not ready
	if(flagsinit) {
	  idsall = 1;
	  newressu_toggleflag("ALL");
	  flagsinit = 0;
	}
	flagdigits = 1; // semicolon separated (flags)
	
      } else {
	ok = 0;
      }

      unsigned char buffer[32];

      int ok2 = 0;
      
      // command line parameters for flags
      
      if(!strncmp(argv[c], "--", 2)) {
	if(flagsinit) {
	  idsall = 0;
	  newressu_toggleflag(buffer);
	  flagsinit = 0;
	}
	strcpy(buffer, argv[c] + 2); // as is, skip dashes
	if(newressu_toggleflag(buffer) == 1)
	  ok2 = 1;
	else {
	  strtolower(buffer); // all letters lowercase
	  if(newressu_toggleflag(buffer) == 1)
	    ok2 = 1;
	  else {
	    buffer[0] = toupper(buffer[0]); // first letter uppercase
	    if(newressu_toggleflag(buffer) == 1)
	      ok2 = 1;
	    else {
	      strtoupper(buffer); // all letters uppercase
	      if(newressu_toggleflag(buffer) == 1)
		ok2 = 1;
	    }
	  }
	}
      }
      if(flagflags && ok == 0 && ok2 == 0) {
	fprintf(stderr,"%s: invalid option %s\n", procname, argv[c]);
	exit(1);
      }
      if(!flagflags && ok == 0 && ok2 == 0) {
	fprintf(stderr,"%s: invalid option %s\n", procname, argv[c]);
	exit(1);
      }
      if(!flagflags && ok == 0 && ok2 == 1) {
	fprintf(stderr,"%s: invalid option '%s' without --flags\n", procname, argv[c]);
	exit(1);
      }
    } // if(!strncmp
  } // for(c = 0

  clearcvar();
  
  if(size == -1 && base != -1) {
    if(base == 2)
      size = 8;
    else if(base == 8)
      size = 3;
    else if(base == 10)
      size = 5;
    else if(base == 16)
      size = 4;
    else
      size = 8;
  }

  if(size == -1 && base == -1)
    size = 5;
  
  if(base != -1) {
    digitsext = digits;
    charspaces = 0;
    charwidth = 1;
  }
  
  if(flagflags) {

    digits = NULL;
    flagdigits = 1; // semicolon separated (flags)

    for(d = 0; d < sizeof(idsflags) / sizeof(idsflags[0]); d++) {
      unsigned char buffer[32];
      if(flagids[d] == 1) {
	strcpy(buffer,idsflags[d].id);
	strcat(buffer,";");
	digits_add_string(&digits, buffer);
      }
    }

    if(digits == NULL)
      digits = "🇫🇮;";
    else
      digitsext = digits;

    //digits = "🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿";
    //digits = "🇫🇮🇸🇪🇳🇴🇩🇰🇪🇪🇱🇻🇱🇹";
    
  }		       

#define aDEBUG76
#ifdef DEBUG76

  if(flagidflags) {
    int first = 1;
    for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
      if(flagids[c] == 1) {
	if(first) {
	  fprintf(stdout,"flags: ");
	  first = 0;
	}
	fprintf(stdout," %s",idsflags[c].id);
      }
    }
    if(!first)
      fprintf(stdout,"\n");
  }

#endif

#ifdef DEBUG59

  if(utf8) {

    int xlines;
    printcolumns(6, 0x10, 0, 64, &xlines);
    
    int utf8output = 0;
    for(c = 0; c < 65535 * 4; c++) {
      //for(c = 0x2800; c < 0x2900; c++) { // braille
      unsigned char buffer10[10];
      if(c % 64 == 0) {
	if(c > 0) {
	  fprintf(stdout,"\n");
	  utf8output = 0;
	}
	fprintf(stdout,"%5x ", c);
	utf8output = 1; 
      }
      if(c >= 0 && c < 32) {
	c += 31;
	fprintf(stdout, "%-32s", "--- control characters ---");
	utf8output = 1;
      } else if(c >= 128 && c < 256) {
	c += 31;
	fprintf(stdout, "%-32s", "--- utf8 characters ---");
	utf8output = 1;
      } else {
	codetoutf8(buffer10, c);
	fprintf(stdout,"%s", buffer10);
	utf8output = 1;
      }
    }
    if(utf8output)
      fprintf(stdout,"\n");
    fflush(stdout);

    return(0);
  }

#endif
  
#define aDEBUG60 2

#ifdef DEBUG60
    int xlines;
    printcolumns(0, 2, 0, 64, &xlines);
    printcolumns(0, 8, 0, 64, &xlines);
    for(c=1;;c*=10) {
      fprintf(stdout,"c:%d\n",c);
      printcolumns(0, 10, 0, c, &xlines);
    }
    printcolumns(0, 16, 0, 64, &xlines);
#endif

  if(size == 0)
    size = 1;
  else if(size > 1024)
    size = 1024;
  if(lines < 1)
    lines = 1;

#ifdef USE_TIMER
  timerstart = getseconds();
#endif

  if(flagdigits) // semicolon separated (flags)
    digitscount = utf8strings(digits);
  else // not
    digitscount = utf8characters(digits);

  //digitscount = utf8characters(digits);
  
  if(flagdigits) // semicolon separated (flags)
    characterlengths = utf8stringlengths(digits);
  else
    characterlengths = utf8lengths(digits);

  //characterlengths = utf8lengths(digits);

#ifdef FORT
  if(input == INPUT_FORT ||
     input == INPUT_FORTXOR ) {
    strcpy(fort_random_file, "newressufort.rnd");
    strcpy(fort_secret_file, "newressufortsecret.rnd");
    //fort_verbose = 0;
    fort_init();
  }
#endif

  if(input == INPUT_STREAM) {
    if(key == NULL)
      key = stream_default_key;

    stream_open(0, key);

  } else if(key != NULL) {
    fprintf(stderr,"%s: cannot --key without --stream\n", procname);
    exit(2);

  }

  if(fixedclock && !copyreverse) {
    fprintf(stderr,"%s: cannot --fixedclock without --copyreverse\n", procname);
    exit(2);

  }
  if(dieharder && !sample) {
    fprintf(stderr,"%s: cannot --dieharder without --sample\n", procname);
    exit(2);
  }

  if(purge_set && (!dieharder || !sample)) {
    fprintf(stderr,"%s: cannot --purge or --save without --sample and --dieharder\n", procname);
    exit(2);
  }

  if((filesize_set || blocksize_set || blocks_set) && !sample) {
    fprintf(stderr,"%s: cannot --filesize, --blocks or --blocksize without --sample\n", procname);
    exit(2);
  }

  if(input == INPUT_TEST) {
    fprintf(stderr,"%s: randomness from your generator (test_bytes)\n", procname);
  }

  if(sample) { // & dieharder
    dump_sample();
    exit(status);
  } // if(sample)

#ifdef DEBUG19

  if(flagint) {
    unsigned char savepath[128];

    save_path(sizeof(savepath), savepath);

    if(!strncmp(procname, "/bin/newressu", 13) && exists_path("/var/ressu"))
      set_path("/var/ressu");
    else if(!strncmp(procname, "./newressu", 10) && exists_path(".ressu"))
      set_path(".ressu");
    else if(exists_path("/var/ressu"))
      set_path("/var/ressu");
    else if(exists_path("/var/newressu"))
      set_path("/var/newressu");
    else if(exists_path(".ressu"))
      set_path(".ressu");
    else
      set_path("./");

    unsigned char command[160], date[16], filename[64];
    command_readline("date +%Y%m%d%H", sizeof(date), date);
    //command_readline("date +%Y%m%d%H%M", sizeof(date), date);

    sprintf(filename,"newressutest14.rnd.%s", date);
    sprintf(command,"./newressutest14.sh >%s",filename);
    //fprintf(stdout,"date:%s, filename:%s\n", date, filename);

    if(!exists_path(filename)) {
      int error;
      if((error = system(command)) != 0) {
	fprintf(stderr,"%s: system(): cannot execute command '%s'\n", procname, command);
      }
    }
    //fprintf(stderr," done.\n");
    fflush(stderr);

    set_path(savepath);
  } // if(flagint

#endif
  
  // print used digits
  
  if(flagprintdigits) {
    int count = 0;
    unsigned char *p;

    fprintf(stdout,"digits:");
    
    p = digits;
    while(*p != '\0') {
      if(*p < 0x80 || // ascii char
	 *p > 0xbf) { // first utf8 byte
	count++;
#ifdef KOK
	if((charwidth == 2 && count >= 32) ||
	   (charwidth == 1 && count >= 72) )
	  break;
#endif
      }
      fprintf(stdout,"%c", *p);
      p++;
    }
    if(*p != '\0')
      fprintf(stdout,"...");
    fprintf(stdout,"\n");
  }

  // get linenumber length in digits

  plinesdigits = line_number_length();

  // get data length in digits

  if(limit != 0) {
    unsigned char wordbuf[128];
    out_word(sizeof(wordbuf), wordbuf, digits, limit-1);
    size = utf8characters(wordbuf);
  }

  pchars = 0;
  pwords = 0;

  // in beginning of line, count printed line number
      
  if(!quiet && slineno) {
    sprintf(linenobuf,"%0*llu", plinesdigits, plines);
    pchars += strlen(linenobuf);
    pchars++;
  }

  // count words

  cwords = 0;
  
  while((chars > 0 && pchars + size * charwidth + calc_spaces(pwords) <= chars) ||
	(words > 0 && pwords < words)) {
    
    pchars += calc_spaces();
    pchars += (size * charwidth);
    pwords++;
    cwords++;
  }

  // there has to be atleast one data word
  
  if(pwords < 1) {
    pchars += calc_spaces();
    pchars += (size * charwidth);
    pwords = 1;
  }

  unsigned long wordvalues = 1, wordvaluesold;

  for(c = 0; c < size; c++) {
    wordvaluesold = wordvalues;
    wordvalues *= digitscount;
    if(wordvalues / digitscount != wordvaluesold) {
      wordvalues = 0;
      break;
    }
  }

  if(limit > 0) {
    if(sort == 1 && limit - !zero < words) {
      fprintf(stderr, "%s: limit is less than words (zero)", procname);
      fprintf(stderr, ", limit:%lu", limit);
      fprintf(stderr, ", words:%d", words);
      fprintf(stderr, ", zero:%d", zero);
      fprintf(stderr, "\n");
      
      exit(2);
    }
  } else {
    if(sort == 1 && size > 0 && wordvalues > 0 && wordvalues < pwords) {
      fprintf(stderr, "%s:", procname);
      fprintf(stderr, " digits is less than calculated words");
      fprintf(stderr, ", digits:%d(%lu)", digitscount, wordvalues);
      fprintf(stderr, ", words:%d\n", pwords);

      exit(2);
    }
  }

  // "small" words as single newressu_gen_limit() call
  
  if(limit == 0 && wordvalues > 0)
    limit = wordvalues;

  if(columns) {
    int xlines;
    printcolumns(0, 10, 0, pchars, &xlines);
    lines -= xlines;
    if(lines < 1)
      lines = 1;
  }
  
#ifdef TEST
  if(flagint && base != -1) {
    fprintf(stderr,"Last word: ");
    fprintfbase(stderr, limit - 1, base);
    fprintf(stderr,"\n");
  }
#endif

  if(help) {
    struct helpline {
      char *command;
      char *text;
    } helplines[] = {
      { "newressu --help/-?", "this help page" },
      { "newressu -d/--dec", "print random decimal digits (default)" },
      { "newressu -o/--oct", "octal digits" },
      { "newressu -x/--hex", "hexadecimal digits" },
      { "newressu -b/--bin", "binary digits" },
      { "newressu -d --space", "decimal digits, with spaces between \"words\"" },
      { "newressu -b --space", "binary digits, with spaces between \"words\"" },
      { "newressu -d -l30", "decimal digits, 30 lines" },
      { "newressu -d -l30 --lineno", "decimal digits, 30 lines, no linenumbers"  },
      { "newressu --base2", "base 2 digits =decimal (0-1)" },
      { "newressu --base8", "base 8 digits =octal (0-7)" },
      { "newressu --base10", "base 10 digits =decimal (0-9)" },
      { "newressu --base16", "base 16 digits =hexadecimal (0-F)" },
      { "newressu --base62", "base 62 digits (0-9, A-Z, a-z)" },
      { "newressu --rand", "numbers in rand style listing"  },
      { "newressu --space 2", "numbers in 2 number groups"  },
      { "newressu --newline 5", "print numbers in 5 line groups"  },
      { "newressu -l*", "fill all screen lines"  },
      { "newressu -c*", "fill all screen columns"  },
      { "newressu --screen", "fill screen columns and lines"  },
      { "newressu -d -c128", "print decimal digits, 128 characters per line"  },
      { "newressu -d --lim10", "print decimal numbers between 0-9" },
      { "newressu -d --lim10 -x","print hexadecimal numbers with decimal limit" },
      { "newressu --isupper --limBAAAAA","print five letter uppercase words" },
      { "newressu -d -s10 --space","print decimal numbers with spaces and wordsize 10" },
      { "newressu -d --space --zero --lim7","print rollings of dice (1-6)" },
      { "newressu -b -s1 --space","print throws of coin (0,1)" },
      { "newressu -d --lim41 -w7 --zero --lotto","print lotto numbers for finnish lotto 7x(1-40)" },
      { "newressu -d -s5 --sort -w16","print 16 sorted decimal numbers from 0 to 99999" },
      { "newressu --alnum", "alphanumeric characters" },
      { "newressu --alpha", "alphabetic characters" },
      { "newressu --graph", "printables excluding space" },
      { "newressu --lower", "lowercase characters" },
      { "newressu --punct", "punctuation characters" },
      { "newressu --upper", "uppercase characters" },
      { "newressu -1", "material for passwords" },
      { "newressu --dnk/--nor", "danish/norwegian alphabet" },
      { "newressu --fin/--swe", "finnish/norwegian alphabet" },
      { "newressu --rus", "russian alphabet" },
      { "newressu --est", "estonian alphabet" },
      { "newressu --ltu", "lithuanian alphabet" },
      { "newressu --lva", "latvian alphabet" },
      { "newressu --fra/--gbr/--usa/--ita", "french/gb/us/italian alphabet" },
      { "newressu --deu", "deutsch alphabet" }, 
      { "newressu --grc", "greek alphabet" }, 
      { "newressu --jp", "japan alphabet (hiragana, katakana, kanji) " }, 
      { "newressu --jp1/--hir", "japan alphabet (hiragana) " }, 
      { "newressu --jp2/--kat", "japan alphabet (katakana) " }, 
      { "newressu --jp3/--kan", "japan alphabet (kanji) " }, 
      { "newressu --cn", "chinese alphabet" }, 
      { "newressu --heb", "hebrew alphabet" }, 
      { "newressu --hin/--ind", "hindi alphabet" }, 
      { "newressu --kor", "korean alphabet" }, 
      { "newressu --got", "gothic alphabet" }, 
      { "newressu --otp5n/--otp1", "\"one time pad\" (otp) with 5 numeric characters" }, 
      { "newressu --otp5a/--otp2", "otp with 5 uppercase letters" }, 
      { "newressu --otp4a/--otp3", "otp with 4 uppercase letters" }, 
      { "newressu --cards", "playing cards" }, 
      { "newressu --cardsuits", "playing card suits" }, 
      { "newressu --chessmen", "chess men" }, 
      { "newressu --dice", "print dice" },
      { "newressu --mahjong", "print mahjong pieces" },
      { "newressu -i▌▙▄ / --pattern1", "print pattern1" },
      { "newressu -i◜◝◞◟ / --pattern2", "print pattern2" },
      { "newressu -i\\\\/ / --pattern3", "print pattern2" },
      { "newressu -i▧▨ / --pattern5", "print pattern2" },
      { "newressu --ressu", "use randomness from ressu (default)" },
      { "newressu --ressu", "use randomness from ressu (default)" },
      { "newressu --pseudoressu", "use randomness from pseudo random ressu" },
      { "newressu --fast/--fastressu", "use randomness from fast ressu" },
      { "newressu --single/--singleressu", "use randomness from single round of ressu" },
#ifdef FORT
      { "newressu --fort", "use randomness from fort" },
#endif
#ifdef USE_RDRAND
      { "newressu --rdrand", "use randomness from intel rdrand" },
#endif
#ifdef USE_RDSEED
      { "newressu --rdseed", "use randomness from intel rdseed" },
#endif
      { "newressu --urandom", "use randomness from /dev/urandom" },
#ifdef USE_RANDOM
      { "newressu --random", "use randomness from /dev/random" },
#endif
    };
    
    for(c = 0; c < sizeof(helplines) / sizeof(helplines[0]); c++) {
      fprintf(stdout, "%-50s", helplines[c].text);
      fprintf(stdout, "%-25s", helplines[c].command);
      fprintf(stdout, "\n");
    }

#define DEBUG77 2

#ifdef DEBUG77

    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;
    unsigned char name[128];
    
    a = areaflags;
    while(*a != '\0' && newressu_getname(sizeof(name), name, &a)) {
      fprintf(stdout,"area:%s",name);
      int count = 0;
      for(c = 0; c < sizeof(idsflags) / sizeof(idsflags[0]); c++) {
	if(!strcmp(name, "ALL")) {
	  count++;
	  unsigned char *q = idsflags[c].flags;
	  unsigned char name2[128], name3[128];
	  newressu_getname(sizeof(name2), name2, &q); // flag
	  newressu_getname(sizeof(name2), name2, &q); // 2 char isocode
	  newressu_getname(sizeof(name3), name3, &q); // 3 char isocode
	  newressu_getname(sizeof(name3), name3, &q); // name
	  fprintf(stdout,", %s(%s)",name3, name2); // name and isocode2 needed
	} else {	
	  
	  if(newressu_strstr(idsflags[c].flags, name) != NULL) {
	    count++;
	    unsigned char *q = idsflags[c].flags;
	    unsigned char name2[128], name3[128];
	    newressu_getname(sizeof(name2), name2, &q); // flag
	    newressu_getname(sizeof(name2), name2, &q); // 2 char isocode
	    newressu_getname(sizeof(name3), name3, &q); // 3 char isocode
	    newressu_getname(sizeof(name3), name3, &q); // name
	    fprintf(stdout,", %s(%s)", name3, name2); // name and isocode2 needed
	  }
	}
      }
      fprintf(stdout,", count:%d",count);
      fprintf(stdout,"\n");
    }
#endif

    for(c = 0; c < chars; c++)
      fprintf(stdout, "*");
    fprintf(stdout, "\n");
    
    if(lines > 1)
      lines = 1; // print one line below help as a sample
  }

  if(lines == 0)
    exit(status);

#define aDEBUG78 2
    
#ifdef DEBUG78

    for(c = 0; c < sizeof(flagchars) / sizeof(flagchars[0]); c++) {
      int first = 1;
      for(d = 0; d < sizeof(flagchars) / sizeof(flagchars[0]); d++) {
	char buffer[32];
	buffer[0] = '\0';
	if(!first)
	  strcat(buffer," ");
	strcat(buffer, flagchars[c]);
	strcat(buffer, flagchars[d]);
	fprintf(stdout,"%s",buffer);
	first = 0;
      }
      fprintf(stdout,"\n");
    }
#endif
  
  int linecnt = 0;
  unsigned char *line = NULL;
  unsigned char wordbuf[1025];
  
  for(;;) {

    if(!sort) { // no sort, no lotto

      for(cwords = 0; cwords < pwords; cwords++) {
	readword(wordbuf);

	if(!quiet) {

	  // in beginning of line, print line number

	  print_line_number();
	
	  // want to print spaces between "words"?

	  print_spaces(' ');
	
	  // print word

	  print_word(wordbuf);

	  newressu_output = 1;
	}

      } // for(cwords = 0; cwords < pwords; cwords++) {
    } else { // if(!sort)

      line_clear(&linecnt, &line);

      // fetch and save words on this row

      for(cwords = 0; cwords < pwords; /*!*/) {
	readword(wordbuf);

	if(line_add_string_sort(&linecnt, &line, wordbuf)) {
	  cwords++; // added if unique
	}
      } // while(cwords < pwords) {

      // print words on this row

      for(cwords = 0; cwords < pwords; cwords++) {

	line_get_string(sizeof(wordbuf), wordbuf, cwords, line);

	if(!quiet) {

	  // in beginning of line, print line number

	  print_line_number();
	
	  // want to print spaces between "words"?
	
	  print_spaces(' ');

	  // print word
	
	  print_word(wordbuf);

	  newressu_output = 1;
	}
      } // end of for(cwords = 0; cwords < pwords; cwords++
    } // if(!sort)

    if(!quiet) {
      fprintf(stdout, "\n");
    }

    plines++;
    ptotallines++;

    // print empty line

    if(!quiet &&
       snewline > 0 &&
       plines%snewline == 0) {
      // if screenfull printed, use
      // total lines (contains also
      // empty lines), if not
      // screenfull use printed
      // lines (without empty lines)
      if((screen && ptotallines < lines) ||
	 (!screen && plines < lines)) {
	fprintf(stdout, "\n");
	ptotallines++;
      }
    }

    //fflush(stdout);
    
    newressu_output = 0;
    
    // all needed lines printed?

    if(screen && snewline > 0 &&
       ptotallines >= lines)
      break;
    if(plines >= lines)
      break;

#define STATDIV (1024 * 1024 * 100)
    
    if(print_statline) {
      if(isatty(STDOUT_FILENO)) { // 0=stdin, 1=stdout, 2=stderr
	print_statline = 0;
      } else {
	if(lines % 1000 == 0) {
	  unsigned char buf10[10];
	  unsigned long long bytes;
	  int pros = (int)(((double)plines / lines) * 100);

	  bytes = (((unsigned long long)size * pwords * plines) / STATDIV) * STATDIV;
	  stat_line_get_readable(buf10, bytes);
	  
#ifdef DEBUG97
	  fprintf(stderr, "%lld", (unsigned long long)size * pwords * plines);
	  fprintf(stderr, ", %lld", bytes);
	  fprintf(stderr, ", %s", buf10);
	  fprintf(stderr, "\n");
#endif
	  stat_line_begin();
	  stat_line_printf("%s characters written:", input_str);
	  stat_line_readable((unsigned long) size * pwords * plines);
	  stat_line_printf(", %d%%", pros);
	  //stat_line_printf(", lines:%lld",lines);
	  //stat_line_printf(", plines:%lld",plines);
	  stat_line_end();
	}
	stat_line_cursor();
      }
    } // if(print_statline)
  } // for(;;)

  if(print_statline) { // 0=stdin, 1=stdout, 2=stderr
    stat_line_begin();
    stat_line_end();
    stat_line_cursor_remove();
  }

#ifdef DEBUG2H

  int itemlen = 0;
  for(int c = 0; c < ressuct_bytes; c++) {
    unsigned char buffer[16];
    sprintf(buffer, "%lu", count[c]);
    if(itemlen < strlen(buffer))
      itemlen = strlen(buffer);
  }
  for(int c = 0; c < ressuct_bytes; c++) {
    if(c % 16 == 0) {
      if(c > 0)
	fprintf(stdout,"\n");
      fprintf(stdout,"%05u ", c);
    }
    fprintf(stdout,"%*lu", itemlen + 1, count[c]);
  }
  fprintf(stdout,"\n");

#endif
  
#ifdef USE_TIMER

  if(timer) {
    double timertook = getseconds() - timerstart;
    fprintf(stderr, "%s run time %f seconds", input_str, timertook);
    fprintf(stderr, ", %lld lines", plines);
    fprintf(stderr, ", %f useconds/line", timertook * 1000000 / plines);
    fprintf(stderr, ", %d characters/line", pwords * size);
    fprintf(stderr, ", %f useconds/character",
	    (timertook * 1000000 / plines) / (pwords * size) );
    fprintf(stderr, "\n");
  }

#endif

  fflush(stdout);

  if(digitsext != NULL)
    free(digitsext);
  
#ifdef FORT

  if(input == INPUT_FORT ||
    input == INPUT_FORTXOR) {
    fort_save();
  }

#endif
  newressu_clear();
  
  exit(status);
}

#endif // MAIN

Lisäsin loppuun vielä newressun vielä julkistamattoman version (en saanut lippuja toimimaan oikein.. Katso taaksepäin:

Published
Categorized as muuta

Leave a comment