Kaikki oikeudet pidätetään ©. Artikkelissa syntyvä ohjelma on kokeiltavana täällä https://moijari.com:5008/. Tein muutoksia myös html-versioon, ja käynnistin myös html-version serveristä. Se on portissa 5009. Html version linkki löytyy myös sivun https versiosta. Olisin kiitollinen jos hetken clikkailisit linkkejä, niin saisin tarkistaa että ne toimivat oikein.
Jos pidät sudokujen ratkaisusta niitä löytyy posteista: https://moijari.com/?p=2930 ja https://moijari.com/?p=1874.
Jos taas satunnaisbitit kiinnostavat postissa https://moijari.com/?p=1874 esitellään satunnaisbittigeneraattori ressu. Ensimmäinen maininta ressu satunnaisbittigeneraattorista: https://moijari.com/?p=62.
Tämä artikkeli nojaa aika paljon artikkeleissa https://moijari.com/?p=2930 ja https://moijari.com/?p=1874 kehitettyyn db8 ohjelmaan.
Seuraavaksi kokeilen taas tehdä palvelimen, joka lukee seuraavaa rakennetta. Edellinen yritys oli tälläinen: https://moijari.com/?p=1799 ja tälläinen https://moijari.com/?p=1256. Tämä on taas pidempi artikkeli tai artikkelisarja.
'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"
Edellisessä scriptissä on maat (country), yritys (company), asiakas (customer), tuote (product), lasku(bill) ja liiketapahtuma (transaction). Tämä on tälläinen yksinkertaistettu malli, jossa syötetään lasku, keräillään sen perusteella (ei tilausta, toimitusta, keräilyä jne.). Samoin liiketapahtumat perustuu yksinkertaiseen kirjanpitoon. Ajatus on että näiden perusteella voin miettiä mitä toimintoja terttuun tarvitaan.
Lukijalle jää mahdollinen tilauksen lisääminen, osto- ja myyntireskontra, laskujen maksaminen, liiketapahtumien muutos kaksinkertaiseksi, kirjanpidon tilien lisääminen, tilien saldot, tulos ja taselaskelma, ja mitä muuta?
Itse jäin pohtimaan pitäisikö liiketapahtumien olla kuvattu kuten laskutapahtumat (bill) ilman erillistä lines appia.
Jos pidät artikkeleistani, tarjoa vissy.
Ote lokista
Tässä ote https-lokista: ajo alkaa starting dbs3:lla rivillä, lapsiprosessin suoritus loppuu unlink rivillä.
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 ========================================
Pääohjelma main()
Pääohjelma lukee komentoriviparametrit –http, –https ja –port ja käynnistää niiden perusteella http- tai https-palvelimen oikealla porttinumerolla. Oletuksena luodaan http palvelin porttinumerolla 5000.
Lisäksi ohjelma muodostaa tämän suoritettavan tiedoston tiivisteen, joka tulostetaan aina sivun loppuun (htmldigest).
int http = 1;
int https = 0;
void main(int argc, char *argv[])
{
int c;
procname = argv[0];
unsigned char filedigest[HashLen];
dbs_file_digest("/proc/self/exe", filedigest);
htmldigest[0] = '\0';
for(int c = 0; c < HashLen; c++) {
char twodigits[3];
sprintf(twodigits, "%02x", filedigest[c]);
strcat(htmldigest, twodigits);
}
//
// look thru command line parameters
//
for(c = 1; c < argc; c++) {
if(!strncmp("-", argv[c], 1)) {
if(!strncmp("--port", argv[c], 6)) {
if(*(argv[c] + 6) != '\0')
myport = argv[c] + 6;
else if(c + 1 < argc) {
myport = argv[c + 1];
c++;
}
} else if(!strcmp("--https", argv[c])) {
https = 1;
http = 0;
} else if(!strcmp("--http", argv[c])) {
http = 1;
https = 0;
} else {
log_errprintf("%s: invalid option %s\n", procname, argv[c]);
exit(1);
}
}
}
log_errprintf("starting dbs3 \"%s\"", programname);
log_errprintf(", port:%s", myport);
if(http)
log_errprintf(", http");
if(https)
log_errprintf(", https");
log_errprintf("\n");
if(http)
http_server();
if(https)
https_server();
}
Http palvelin
Http palvelin ajaa tarvittavia palvelimen käynnistykseen liittyviä rutiineja server_basic_socket() rutiinilla ja luo uuden prosessin fork():illa lapsiprosessia varten.
static void http_server()
{
int quit, reset, addr_size;
struct sockaddr_in sa_cli;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// plus space for '\0'
htmlin = malloc(htmlinlen + 1);
reset = 1;
quit = 0;
for(;;) {
log_mode = 1;
if(quit) {
break;
}
if(reset) {
if(s != -1)
close(s);
log_printf("server_basic_socket()\n");
s = server_basic_socket();
reset = 0;
}
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
log_errprintf("%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
fprintf(stdout,"========================================\n");
log_printf("dbs_time_vars()\n");
dbs_time_vars();
if(beepaccept) {
fprintf(stderr,"\a\n");
fflush(stderr);
}
pid_t pid;
log_printf("Fork start (parent)");
log_printf(" getpid:%d getppid:%d", getpid(), getppid());
log_printf("\n");
log_printf("fork()\n");
if((pid = fork()) < 0) {
log_errprintf("%s: cannot fork()", procname);
log_errprintf(", errno %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
fflush(stderr);
perror("fork");
fflush(stderr);
exit(1);
} else if(pid == 0) { // child
log_printf("init_child()\n");
init_child();
log_mode = 2; // child
log_printf("close(s)\n");
close(s);
log_printf("Fork start (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("close(s)\n");
close(s);
log_printf("http_client()\n");
http_client(news, sa_cli, addr_size, "http");
dbs_run_critical_sections();
log_printf("server_close(news)\n");
server_close(news);
log_printf("Fork end (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("exit_child()\n");
exit_child();
log_mode = 1;
exit(0);
}
log_printf("Fork end (parent)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("server_close()\n");
server_close(news);
} // for(;;)
}
server_basic_socket()
Seuraavaa rutiinia käytetään sekä http että https palvelimessa.
static int server_basic_socket()
{
int s;
struct addrinfo *res;
log_printf("server_getaddrinfo()\n");
server_getaddrinfo(myport, &res);
log_printf("server_socket()\n");
s = server_socket(res);
log_printf("server_bind()\n");
server_bind(s, res);
log_printf("freeaddrinfo()\n");
freeaddrinfo(res);
log_printf("server_listen()\n");
server_listen(s);
return(s);
}
server_getaddrinfo() ja muuta
Edellisen rutiinin aliohjelmia
static int server_getaddrinfo(unsigned char *myport, struct addrinfo **res)
{
int status;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
log_printf("getaddrinfo()\n");
if ((status = getaddrinfo(NULL, myport, &hints, res)) != 0) {
#ifdef OLD1
fprintf(stderr, "%s: getaddrinfo error: %s",
procname, gai_strerror(status));
fprintf(stderr,", error code %d\n", status);
#endif
log_errprintf( "%s: getaddrinfo error: %s",
procname, gai_strerror(status));
log_errprintf( ", error code %d\n", status);
//fflush(stderr);
}
return(status);
}
static int server_socket(struct addrinfo *res)
{
int s;
log_printf("socket()\n");
if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
log_errprintf("%s: socket()", procname);
log_errprintf(", errno: %d", errno);
log_errprintf("(%s)\n", strerror(errno));
perror("socket");
//fflush(stderr);
}
return(s);
}
static void server_bind(int s, struct addrinfo *res)
{
log_printf("bind()\n");
if(bind(s, res->ai_addr, res->ai_addrlen) == -1) {
int errerrno = errno;
if(errerrno == 98) {
fprintf(stdout,"%s cannot bind, waiting to bind", procname);
while(errerrno == 98) {
sleep(10);
fprintf(stdout,".");
fflush(stdout);
bind(s, res->ai_addr, res->ai_addrlen);
errerrno = errno;
}
fprintf(stdout,"bind done!\n");
//fflush(stdout);
} else {
int errerrno = errno;
log_errprintf("%s: cannot bind()", procname);
log_errprintf(", errno: %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("bind");
//fflush(stderr);
}
}
}
static int server_listen(int s)
{
int retval;
log_printf("listen()\n");
if((retval = listen(s, backlog)) == -1) { // ==!
int errerrno = errno;
log_errprintf("%s: cannot listen()", procname);
log_errprintf(", errno %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("listen");
//fflush(stderr);
}
return(retval);
}
static void server_close(int s)
{
log_printf("close()\n");
if(close(s) == -1) {
int errerrno = errno;
log_errprintf("%s: cannot close()", procname);
log_errprintf(", errno %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("close");
//fflush(stderr);
}
}
Http client
Http client lukee asiakkaan pyynnön read():lla, suorittaa asiakasohjelman dbs_run_loop():lla, ja kirjoittaa tulokset write():lla.
static void http_client(int news, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
unsigned char buffer10[10];
htmlparams = NULL;
htmlin[0] = '\0';
dbs_server_vars(sa_cli, addr_size, name);
while(htmlparams == NULL ||
clen - strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
struct pollfd fds;
fds.fd = news;
fds.events = POLLIN;
bytes = 0;
int retval = poll(&fds, 1, 1000 * 10);
log_printf("******poll: %d\n", retval);
if(retval > 0) { // -1 err, 0 expire
log_printf("read()\n");
if((bytes = read(news, htmlin + totalbytes, htmlinlen - totalbytes)) < 0) {
log_errprintf("%s: cannot read()\n", procname);
perror("read");
//fflush(stderr);
}
if(retval > 0)
reads++;
}
log_printf("(%d bytes)", bytes);
log_printf("%s", htmlin);
if(bytes == 0)
break;
if(bytes > 3 &&
!isprint(htmlin[0]) &&
!isprint(htmlin[1]) &&
!isprint(htmlin[2])) {
log_printf("https packet?\n");
htmlin[0] = '\0';
totalbytes = 0;
bytes = 0;
break;
}
*(htmlin + totalbytes + bytes) = '\0';
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin = realloc(htmlin, htmlinlen * 2 + 1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(!strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length", sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
if(totalbytes != 0) {
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"");
log_dump_string(htmlin);
log_printf("\"\n");
dbs_run_loop();
log_printf("buffers(html):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
if((bytes = write(news, html_get_string(c), strlen(html_get_string(c)))) == -1) {
log_errprintf("%s: cannot write() dbs_html[%d]\n", procname, c);
perror("write");
//fflush(stderr);
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n",html_get_string(c));
}
log_printf("\n");
}
dbs_query_vars();
}
Https palvelin
Ohjelma toteuttaa https-palvelimen. Palvelimen toimintaa valmistellaan server_https_init() ja server_basic_socket() rutiineilla.
Asiakasohjelmaa varten luodaan uusi prosessi fork():illa. Asiakasohjelma ajetaan https_client() rutiinilla.
static void https_server()
{
int quit, reset, addr_size;
struct sockaddr_in sa_cli;
SSL_CTX *ctx = NULL;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
reset = 1;
quit = 0;
for(;;) {
log_mode = 1;
if(quit) {
break;
}
if(https_keyschange_needed())
reset = 1;
if(reset) {
if(ctx != NULL) {
log_printf("SSL_CTX_free()\n");
SSL_CTX_free(ctx);
}
if(s != -1)
close(s);
log_printf("server_https_init()\n");
ctx = server_https_init();
log_printf("server_basic_socket()\n");
s = server_basic_socket();
reset = 0;
}
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
log_errprintf("%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
fprintf(stdout,"========================================\n");
log_printf("dbs_time_vars()\n");
dbs_time_vars();
pid_t pid;
log_printf("Fork start (parent)");
log_printf(" getpid:%d getppid:%d", getpid(), getppid());
log_printf("\n");
log_printf("fork()\n");
if((pid = fork()) < 0) {
log_errprintf("%s: cannot fork()", procname);
log_errprintf(", errno %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("fork");
fflush(stderr);
exit(1);
} else if(pid == 0) { // child
log_printf("init_child()\n");
init_child();
log_mode = 2; // child
log_printf("close(s)\n");
close(s);
log_printf("close(s)\n");
close(s);
log_printf("https_client()\n");
https_client(news, ctx, sa_cli, addr_size, "https");
dbs_run_critical_sections();
log_printf("server_close(news)\n");
server_close(news);
log_printf("Fork end (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("exit_child()\n");
exit_child();
exit(0);
}
log_printf("Fork end (parent)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("server_close()\n");
server_close(news);
} // for(;;)
}
server_https_init()
server_https_init() kutsuu SSL palvelimen tarvitsemia kutsuja. Uusi koodi tässä tekee SSL avaintenmuutoksen: siitä lisää myöhemmin.
static SSL_CTX *server_https_init()
{
SSL_METHOD *method = NULL;
SSL_CTX *ctx = NULL;
unsigned char cert_digest2[HashLen]; // before change
unsigned char privatekey_digest2[HashLen];
unsigned char cert_digest3[HashLen]; // after change
unsigned char privatekey_digest3[HashLen];
log_printf("SSL_library_init()\n");
SSL_library_init();
log_printf("OpenSSL_add_ssl_algorithms()\n");
OpenSSL_add_ssl_algorithms();
log_printf("OpenSSL_add_ciphers()\n");
OpenSSL_add_all_ciphers();
log_printf("OpenSSL_load_error_strings()\n");
SSL_load_error_strings();
log_printf("SSLv23_server_method()\n");
if((method = (SSL_METHOD *)
SSLv23_server_method()) == NULL) {
log_errprintf("%s: cannot SSLv3_server_method()\n", procname);
//fflush(stderr);
}
log_printf("SSL_CTX_new()\n");
if((ctx = SSL_CTX_new(method)) == NULL) {
log_errprintf("%s: cannot SSL_CTX_new()\n", procname);
}
for(;;) { // 2025 JariK
dbs_file_digest(cert_file, cert_digest2); // save before change digests
dbs_file_digest(privatekey_file, privatekey_digest2);
log_printf("SSL_CTX_use_certificate_file()\n");
if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_certificate_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
log_printf("SSL_CTX_use_PrivateKey_file()\n");
if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_PrivateKey_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
dbs_file_digest(cert_file, cert_digest3); // save after change digests
dbs_file_digest(privatekey_file, privatekey_digest3);
// redo if before stamps are different from after stamps
if(memcmp(cert_digest2, cert_digest3, sizeof(cert_digest3)) ||
memcmp(privatekey_digest2,privatekey_digest3, sizeof(privatekey_digest3)))
continue;
memcpy(cert_digest, cert_digest2, sizeof(cert_digest2));
memcpy(privatekey_digest, privatekey_digest2, sizeof(privatekey_digest2));
log_dump("cert", 32, cert_digest, 32); // first 32 bytes
log_dump("private", 32, privatekey_digest, 32); // first 32 bytes
break;
}
log_printf("SSL_CTX_load_verify_locations()\n");
if(SSL_CTX_load_verify_locations(ctx, cert_file, NULL) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("\n%s: cannot SSL_CTX_load_verify_locations()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
return(ctx);
}
Https client
Https client alustaa SSL yhteyttä SSL toiminnoilla, lukee asiakkaan kyselyn SSL_read():lla ja suorittaa asiakasohjelman dbs_run_loop():lla ja kirjoittaa vastauksen takaisin asiakkaalle SSL_write() rutiinilla:
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int status, ok;
unsigned char buffer10[10];
SSL *ssl;
X509 *peer_cert;
unsigned long long useconds;
useconds = dbs_get_useconds();
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
log_printf("SSL_new()\n");
if((ssl = SSL_new(ctx)) == NULL) {
fprintf(stdout,"\n%s: cannot SSL_new()", procname);
}
log_printf("SSL_set_fd()\n");
if(SSL_set_fd(ssl, news) != 1) {
fprintf(stdout,"\n%s: cannot SSL_set_fd()\n", procname);
}
log_printf("SSL_accept()\n");
if((status = SSL_accept(ssl)) < 0) {
log_printf("%s: cannot SSL_accept(), retval: %d\n", procname, status);
}
log_printf("SSL_get_peer_certificate()");
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
while(htmlparams == NULL || clen - strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
int tries = 0;
for(;;) {
log_printf("SSL_read()\n");
bytes = SSL_read(ssl, htmlin + totalbytes, htmlinlen - totalbytes);
int errerrno, err, err2;
errerrno = errno;
err = SSL_get_error(ssl, bytes);
err2 = ERR_get_error();
log_printf("SSL_read()");
log_printf(", retval %d", bytes);
log_printf(", errno: %d", errerrno);
log_printf(", SSL_get_error(): %d", err);
log_printf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_printf(", %d", err2);
log_printf("\n");
if(bytes >= 0) {
reads++;
break;
}
if(bytes < 0) {
if(++tries < 5 && (err == 1 || err == 5)) {
usleep(1024 * 512 / 5);
log_printf(" try:%d", tries);
continue;
}
log_printf("cannot SSL_read()\n");
ok = 0;
break;
} // if(bytes
break;
} // for(;;)
log_printf("(%d bytes)\n", bytes);
log_printf("%s\n", htmlin);
if(!ok)
break;
*(htmlin + totalbytes + bytes) = '\0';
if(bytes == 0)
break;
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin = realloc(htmlin, htmlinlen * 2 + 1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(!strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"\n");
log_dump_string(htmlin);
log_printf("\"\n");
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
log_printf("SSL_write()\n");
if((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) < 1) {
log_errprintf("%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\n",
procname, c, status, SSL_get_error(ssl, status));
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n", html_get_string(c));
}
}
log_printf("SSL connection using %s\n", htmlsslcipher);
log_printf("dbs_query_vars()\n");
dbs_query_vars();
log_printf("SSL_free()\n");
SSL_free(ssl);
}
DBS_run_loop()
Ohjelma käynnistää dba_loop():n, muotoilee uudestaan dba_loop():in tuloksen (html scripti) ja käynnistää dba_loop2():sen.
static void dbs_run_loop()
{
unsigned char *p;
p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
dbs_html_parse_string(sizeof(htmlpath), htmlpath, &p);
dbs_html_parse_string(sizeof(htmlversion), htmlversion, &p);
dbs_parse_filename(sizeof(htmlfilename), htmlfilename, htmlpath);
dbs_parse_extension(sizeof(htmlfileextension), htmlfileextension, htmlfilename);
htmlparams = dbs_html_get_params();
if(htmlparams == NULL)
htmlparams = "";
if(dbs_html_get_request_line("Host", sizeof(htmlhost), htmlhost) == NULL)
htmlhost[0] = '\0';
log_printf("htmlhost: \"%s\"\n", htmlhost);
if(dbs_html_get_request_line("User-Agent", sizeof(htmluseragent), htmluseragent) == NULL)
htmluseragent[0] = '\0';
log_printf("htmluseragent: \"%s\"\n", htmluseragent);
if(dbs_html_get_request_line("Cookie", sizeof(htmlcookie), htmlcookie)==NULL)
htmlcookie[0] = '\0';
log_printf("htmlcookie: \"%s\"\n", htmlcookie);
html_clear_all();
log_printf("enter dba_loop()\n");
dba_loop();
log_printf("html prettyprinter\n");
#ifdef DEBUG25
log_printf("buffers1:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
for(int c = 1; c < HTML_BUFFERS - 2; c++) {
p = html_get_string(c);
html_set(HTML_BUFFERS - 2);
html_printf("%s", p);
html_set(c);
html_clear();
}
#ifdef DEBUG25
log_printf("buffers2:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
p = html_get_string(HTML_BUFFERS - 2);
html_set(HTML_BUFFERS - 1);
html_indent(p);
html_set(HTML_BUFFERS - 2);
html_clear();
#ifdef DEBUG25
log_printf("buffers3:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
#ifdef DEBUG25
log_printf("html prettyprinter done.\n");
#endif
log_printf("exit dba_loop2()\n");
dba_loop2();
}
get_params(), parse_string(), parse_filename() ja parse_extension()
Seuraavassa edellisen rutiinin käyttämät funktiot:
static unsigned char *dbs_html_get_params()
{
int ok = 0;
unsigned char *p = htmlin;
while(*p != '\0') {
if(!strncmp(p,"\r\n\r\n", 4)) {
p += 4;
ok = 1;
break;
}
p++;
}
if(ok)
return(p);
else
return(NULL);
}
static void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2)
{
int len;
unsigned char *p;
p = *p2;
len = 0;
while(*p != '\0' && !isblank(*p) && *p != '\n' && *p != '\r') {
if(++len < buflen) {
*buf++ = *p;
}
p++;
}
*buf = '\0';
while(isblank(*p))
p++;
*p2 = p;
}
static void dbs_parse_filename(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '/') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
void dbs_parse_extension(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '.') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
html_indent()
Ohjelma formatoi html-tekstin. Puskuri käydään läpi alusta loppuun ja jokaisen tagin kohdalla katsotaan löytyykö tagille pari (joko aloitus tai lopetus). Jos pari löytyy ja tagien välissä on toisia tagejä tehdään sisennys.
int indent;
int printedchars = 0;
#define aDEBUG28
void html_out_crlf()
{
if(printedchars) {
#ifdef DEBUG28
fprintf(stdout,"(%d)", indent * 8 + printedchars);
#endif
html_printf("\n");
#ifdef DEBUG28
fprintf(stdout,"\n");
#endif
for(int c = 0; c < indent; c++) {
html_printf("\t");
#ifdef DEBUG28
fprintf(stdout,"\t");
#endif
}
printedchars = 0;
}
}
#define aDEBUG31 2
void html_parse_name(int size, unsigned char *name, unsigned char **p2)
{
int count;
unsigned char *p, *n;
p = *p2;
count = 0;
n = name;
while(isalpha(*p) || isdigit(*p) || *p == '!') {
if(++count < size)
*n++ = *p;
p++;
count++;
}
*n = '\0';
#ifdef DEBUG31
fprintf(stdout,"[name:%s]", name);
#endif
}
#define aDEBUG36 2
#define aDEBUG37 2
void html_indent(unsigned char *p2) // 2021 JariK
{
int space, ch, tags, tagfound, intag, inchar;
unsigned char *p, *q, *q2, name[32], tag[48];
p = p2;
ch = 0;
indent = 0;
inchar = 0;
while(*p != '\0') {
space = 0;
while(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ') {
p++;
space = 1;
}
if(!strncmp(p,"<br>", 4)) {
p += 4;
html_printf("<br>");
#ifdef DEBUG36
fprintf(stdout,"<br>");
#endif
printedchars += 4;
while(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
p++;
#ifdef DEBUG36
fprintf(stdout,"[nextchar:%c]", *p);
#endif
if(strncmp(p,"</", 2))
html_out_crlf();
}
if(!strncmp(p,"</", 2)) { // Check for end tag
q2 = p;
p += 2;
q = p;
html_parse_name(sizeof(name), name, &q);
q = q2 - 1;
tags = 0;
tagfound = 0;
// Search for start tag backward
sprintf(tag,"<%s", name);
while(q >= p2) {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q--;
}
if(tags && indent > 0) {
indent--;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]", indent);
fprintf(stdout,"[tagfound:%d]", tagfound);
#endif
html_out_crlf();
}
html_printf("</");
#ifdef DEBUG36
fprintf(stdout,"</");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
printedchars += 2;
} else if(*p == '<') { // Check for start tag
p++;
q = p;
html_parse_name(sizeof(name), name, &q);
tags = 0;
tagfound = 0;
// Search for end tag forward
sprintf(tag,"</%s", name);
while(*q != '\0') {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q++;
}
html_out_crlf();
if(tags && tagfound) {
indent++;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]", indent);
fprintf(stdout,"[tagfound:%d]", tagfound);
#endif
}
html_printf("<");
#ifdef DEBUG36
fprintf(stdout,"<");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
printedchars++;
} else if((isprint(*p) || *p>=128) && *p!='\0') {
if(!inchar && !intag) {
inchar = 1;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
//html_out_crlf();
}
int count = 0;
for(q = p; (isprint(*q) || *q>=128) && *q!='\0'; q++) {
if(*q == '\r' || *q == '\n' || *q == '\t' || *q == ' ')
break;
#ifdef DEBUG36
fprintf(stdout,"%c", *q);
#endif
count++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)", count);
#endif
}
int chars = 0;
// calculate number of chars
q = p;
while((*q != '<' && (isprint(*q) || *q >= 128)) && *q != '\0') {
if(*q == '\r' || *q == '\n' || *q == '\t' || *q == ' ')
break;
if(*q < 0x80 || *q > 0xbf) // utf8 too
chars++;
if(*q == '>')
break;
q++;
}
// print line break if needed
if(indent * 8 + printedchars + chars > 100 && !intag) {
html_out_crlf(); // print nl+indent
space = 0;
}
// print space if needed
if(ch != '>' && // no space after tag
*p != '<' && // no space before tag
printedchars > 0 &&
space) {
html_printf(" ");
#ifdef DEBUG36
fprintf(stdout," ");
#endif
space = 0;
}
//print the string
while((*p != '<' && (isprint(*p) || *p >= 128)) && *p != '\0') {
if(*p == '>') {
intag = 0;
}
if(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
break;
ch = *p;
html_printf("%c", *p);
#ifdef DEBUG36
fprintf(stdout,"%c", *p);
#endif
printedchars++;
if(*p == '>') {
p++;
break;
}
p++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)", chars);
#endif
} //while(*p!='\0')
#ifdef DEBUG37
fprintf(stdout,"%s", html[html_now]);
#endif
}
dba_loop()
Ohjelma tulostaa palvelimen palauttaman sivun. Tässä Hello world palvelimessa rutiini ei tee muuta. Sivu ei tässä vaiheessa ole muotoiltu oikein, dba_run_loop() muotoilee sen.
html_set(HTML_HEADER_BUFFER) jälkeiset rivit menevät html otsakkeeseen ja html_set(HTML_PAYLOAD_BUFFER) rivit ovat varsinainen html-scripti joka sisältää veppisivulle tulevan html:n.
popen() kappaleella tulostetaan newressulla satunnaisbittejä.
html_set(HTML_LAST_BUFFER) on viimeinen puskuri, johon tulostetaan vielä footteri ja </body> ja </html>. Välissä oleviin puskureihin voi tulostaa muita html kappaleita. Tässä niitä ei käytetä.
Lopuksi kirjoitetaan päiväys (date) otsakkeen loppuun.
static void dba_loop()
{
log_printf("entering dba_loop()\n");
log_printf("fetching cookies\n");
dbs_get_cookie("terttu_sessionid", sizeof(htmlsessionid), htmlsessionid);
log_printf("htmlsessionid: \"%s\"", htmlsessionid);
dbs_get_cookie("terttu_mode", sizeof(htmlmode), htmlmode);
log_printf(", htmlmode: \"%s\"\n", htmlmode);
dbs_get_cookie("terttu_language", sizeof(htmllanguage), htmllanguage);
log_printf(", htmllanguage: \"%s\"\n", htmllanguage);
log_printf("end fetching cookies\n");
html_set(HTML_HEADER_BUFFER);
html_printf("HTTP/1.0 200 OK\r\n");
html_printf("Location: \r\n");
html_printf("Server: %s\r\n", programname);
html_set(HTML_PAYLOAD_BUFFER);
html_printf("<!doctype html>\r\n");
html_printf("<html lang=\"fi\">");
html_printf("<head>");
html_printf("<meta charset=\"utf-8\">");
html_printf("<title>dbs3</title>");
html_printf("<meta name=\"author\" content=\"Jari Kuivaniemi\">");
html_printf("<meta name=\"copyright\" content=\"Jari Kuivaniemi\">");
html_printf("<meta name=\"format-detection\" content=\"telephone=no\">"); // Safari
html_printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
html_printf("</head>");
html_printf("<body>");
html_printf("<h1>Hello world!</h1>");
html_printf("<p>Tämä on artikkelin <a href=\"https://moijari.com?p=2990\">https://moijari.com?p=2990</a> testiohjelma.");
html_printf(" Ohjelma löytyy tästä linkistä <a href=\"https://moijari.com:5008\">https://moijari.com:5008</a>.</p>");
FILE *fp1;
unsigned char buffer[1024];
if((fp1 = popen("./newressu","r")) != NULL) {
html_printf("<code>");
while(fgets(buffer, sizeof(buffer), fp1) != NULL) {
html_printf("%s<br>", buffer);
}
html_printf("</code>");
pclose(fp1);
}
//html_printf("<p>Tämä on artikkelin https://moijari.com/?p=2990 testiohjelma.");
//html_printf(" Ohjelma löytyy linkistä https://moijari.com:5008/.</p>");
html_set(HTML_LAST_BUFFER);
html_clear();
dba_app_footer();
html_printf("</body>");
html_printf("</html>");
time_t now;
unsigned char timebuf[128];
html_set(HTML_HEADER_BUFFER);
now = time(NULL);
strftime(timebuf, sizeof(timebuf), HTMLTIMEFORMAT, gmtime(&now));
html_printf("Date: %s\r\n", timebuf);
}
dbs_get_cookie()
Seuraavassa edellisen rutiinin käyttämä get_cookie():
void dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value)
{
int len;
unsigned char *p, *n;
value[0] = '\0';
p = htmlcookie;
while(*p != '\0') {
while(isblank(*p))
p++;
if(!strncmp(p, name, strlen(name))) {
p += strlen(name);
while(isblank(*p))
p++;
if(*p == '=')
p++;
while(isblank(*p))
p++;
n = value;
len = 0;
while(*p != ';' && (isprint(*p) || *p >= 0x80)) {
if(++len < valuelen)
*n++ = *p;
p++;
}
*n = '\0';
return;
}
while(*p != ';' && *p != '\n' && *p != '\0')
p++;
if(*p == ';')
p++;
while(isblank(*p))
p++;
}
}
dba_loop2()
Rutiini on jatkoa edelliselle loop rutiinille siinä mielessä että tässä on käytössä formatoitu versio html scriptistä. Rutiini laskee html otsakkeeseen merkkien määrän ja laskee sha256 tiivisteen. Merkkien määrän ja sha256:n laskemisessa ei lasketa otsakkeen merkkejä, ja tulokset laskennasta sijoitetaan otsakkeeseen (HTML_HEADER_BUFFER).
Lopuksi kirjoitetaan otsakkeen ja payload:in välinen merkkisarja “\r\n\r\n”.
static void dba_loop2()
{
int c, len;
log_printf("entering dba_loop2()\n");
html_set(HTML_HEADER_BUFFER);
len = strlen(html_get_string(1)) +
strlen(html_get_string(2)) +
strlen(html_get_string(3)) +
strlen(html_get_string(4)) +
strlen(html_get_string(5)) +
strlen(html_get_string(6)) +
strlen(html_get_string(7)) +
strlen(html_get_string(8));
html_printf("Content-Length: %d\n", len);
unsigned char hash[HashLen];
HashCtx ctx;
#define DEBUG46 2
#ifdef DEBUG46
FILE *fp1;
char *filename = "dbs3sha.deb";
if((fp1 = fopen(filename, "w")) == NULL) {
log_errprintf("%s: cannot open file %s\n", procname, filename);
exit(1);
}
#endif
HashInit(&ctx);
for(c = 1; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)) > 0) {
HashUpdate(&ctx, html_get_string(c), strlen(html_get_string(c)));
//fprintf(stdout,"%d \"%s\"\n", c, html_get_string(c));
#ifdef DEBUG46
fwrite(html_get_string(c), strlen(html_get_string(c)), 1, fp1);
#endif
}
}
HashFinal(hash, &ctx);
#ifdef DEBUG46
fclose(fp1);
#endif
html_printf("SHA256: ");
for(c = 0; c < sizeof(hash); c++) {
html_printf("%02x", hash[c]);
}
html_printf("\n");
html_printf("\r\n\r\n");
log_printf("exiting dba_loop2()\n");
}
Virheilmoitukset lokiin
Aiemmin lokit tulostettiin vain stderr tiedostoon. Tein muutokset, joilla ne päätyvät myös dbs3.log:iin ja dbs3pid*.log:iin. Aiemmin virheilmoitukset toimivat näin:
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
fprintf(stderr,"%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
Uudessa versiossa koodi muutetaan näin:
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
log_errprintf("%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
Vielä koodimuutokset:
void log_wait(); // cross-use with log_printf() routines
void log_post();
void log_printf_valist(FILE *fp1, const char *format, va_list ap) // JariK 2025
{
int count;
static char *printbuf = NULL;
static int printbuf_len = 0;
static int printtime = 1;
va_list ap2;
va_copy(ap2, ap);
count = vsnprintf(printbuf, printbuf_len, format, ap) + 1;
if(printbuf_len < count) {
printbuf_len = count;
printbuf = realloc(printbuf, printbuf_len);
count = vsnprintf(printbuf, printbuf_len, format, ap2) + 1;
}
// print all characters from printbuf.
// print all characters to log adding time and date.
fputs(printbuf, fp1);
FILE *fp2;
if((fp2 = fopen(log_filename, "a")) != NULL) {
if(printtime) {
time_t now = time(NULL);
unsigned char timestamp[32];
log_wait(); // JariK 2025
strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S%Z", localtime((time_t *)&now));
fputs(timestamp, fp2);
fputc(' ', fp2);
printtime = 0;
}
fputs(printbuf, fp2);
fclose(fp2);
if(printbuf[strlen(printbuf) - 1] == '\n') {
printtime = 1;
log_post(); // JariK 2025
}
}
if(log_mode == 2) {
if((fp2 = fopen(log_childfile, "a")) != NULL) {
fputs(printbuf, fp2);
fclose(fp2);
}
}
}
void log_printf(const char *format, ...) // JariK 2025
{
va_list args;
va_start(args, format);
log_printf_valist(stdout, format, args);
//fprintf(stdout,format, args);
va_end(args);
}
void log_errprintf(const char *format, ...) // JariK 2025
{
va_list args;
va_start(args, format);
log_printf_valist(stderr, format, args);
//fprintf(stdout,format, args);
va_end(args);
}
SSL yhteyden avainten vaihto
Rutiini tarkistaa onko ssl avaimet vaihtuneet, ja jos on palauttaa tiedon palvelimelle:
static int https_keyschange_needed() // 2025 JariK
{
unsigned char cert_digest2[HashLen];
unsigned char privatekey_digest2[HashLen];
dbs_file_digest(cert_file, cert_digest2);
dbs_file_digest(privatekey_file, privatekey_digest2);
log_dump("cert", 32, cert_digest2, 32); // first 32 bytes
log_dump("private", 32, privatekey_digest2, 32); // first 32 bytes
if(memcmp(cert_digest, cert_digest2, sizeof(cert_digest2)) ||
memcmp(privatekey_digest, privatekey_digest2, sizeof(privatekey_digest2)))
return(1);
else
return(0);
}
Palvelimen koodi:
for(;;) {
log_mode = 1;
if(quit) {
break;
}
if(https_keyschange_needed())
reset = 1;
if(reset) {
if(ctx != NULL) {
log_printf("SSL_CTX_free()\n");
SSL_CTX_free(ctx);
}
if(s != -1)
close(s);
log_printf("server_https_init()\n");
ctx = server_https_init();
log_printf("server_basic_socket()\n");
s = server_basic_socket();
reset = 0;
}
...
}
}
server_https_init() luuppaa kunnes avainten asetuksen alun ja lopun tiedostotiivisteet ovat koko muutoksen ajan samanlaiset, ja tallettaa viimeiset tiivisteet _digest loppuisiin kenttiin. Luuppaus on siltä varalta että avaimet eivät ole vielä täysin muuttuneet: näin saadaan molemmat avaimet varmasti samasta avainpäivityksestä.
static SSL_CTX *server_https_init()
{
...
for(;;) { // 2025 JariK
dbs_file_digest(cert_file, cert_digest2); // save before change digests
dbs_file_digest(privatekey_file, privatekey_digest2);
log_printf("SSL_CTX_use_certificate_file()\n");
if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_certificate_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
log_printf("SSL_CTX_use_PrivateKey_file()\n");
if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_PrivateKey_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
dbs_file_digest(cert_file, cert_digest3); // save after change digests
dbs_file_digest(privatekey_file, privatekey_digest3);
// redo if before stamps are different from after stamps
if(memcmp(cert_digest2, cert_digest3, sizeof(cert_digest3)) ||
memcmp(privatekey_digest2,privatekey_digest3, sizeof(privatekey_digest3)))
continue;
memcpy(cert_digest, cert_digest2, sizeof(cert_digest2));
memcpy(privatekey_digest, privatekey_digest2, sizeof(privatekey_digest2));
log_dump("cert", 32, cert_digest, 32); // first 32 bytes
log_dump("private", 32, privatekey_digest, 32); // first 32 bytes
break;
}
...
}
Ikonit palauttaa virheilmoituksen
Jos asiakas pyytää tiedoston, jonka pääte (extension) on “.ico” tai “.png”, palautetaan virheilmoitus:
static void dba_loop()
{
....
log_printf("entering dba_loop()\n");
if(!strcmp(htmlfileextension,"ico") ||
!strcmp(htmlfileextension,"png")) {
html_clear_all();
html_set(HTML_HEADER_BUFFER);
html_printf("HTTP/1.0 404 ERROR\r\n");
html_printf("Location: \r\n");
html_printf("Server: %s\r\n", programname);
return;
}
log_printf("fetching cookies\n");
....
}
Https_client()
Kirjoitin https_client rutiinin uudestaan. Uudesta versiosta tuli toivottavasti luettavampi: Uusi versio käyttää kahta puskuria, kun entisessä versiossa oli vain yksi. Vanha versio on #ifdef OLD1:ssä.
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name) // JariK 2025, 2022
{
int status, ok;
unsigned char buffer10[10], buffer[512];
SSL *ssl;
X509 *peer_cert;
unsigned long long useconds;
useconds = dbs_get_useconds();
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
log_printf("SSL_new()\n");
if((ssl = SSL_new(ctx)) == NULL) {
log_errprintf("\n%s: cannot SSL_new()", procname);
}
log_printf("SSL_set_fd()\n");
if(SSL_set_fd(ssl, news) != 1) {
log_errprintf("\n%s: cannot SSL_set_fd()\n", procname);
}
log_printf("SSL_accept()\n");
if((status = SSL_accept(ssl)) < 0) {
log_errprintf("%s: cannot SSL_accept(), retval: %d\n", procname, status);
}
log_printf("SSL_get_peer_certificate()");
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1, tries = 0;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
while(htmlparams == NULL || clen - strlen(htmlparams) > 0) {
log_printf("SSL_read()\n");
if((bytes = SSL_read(ssl, buffer, sizeof(buffer))) < 0) {
int errerrno, err, err2;
errerrno = errno;
err = SSL_get_error(ssl, bytes);
err2 = ERR_get_error();
log_errprintf("SSL_read()");
log_errprintf(", retval %d", bytes);
log_errprintf(", errno: %d", errerrno);
log_errprintf(", SSL_get_error(): %d", err);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
if(++tries >= 5) {
ok = 0;
break;
}
usleep(1024 * 512 / 5);
continue;
}
reads++;
if(bytes == 0)
break;
if(htmlinlen < totalbytes + bytes + 1) {
htmlinlen = totalbytes + bytes + 1;
htmlin = realloc(htmlin, htmlinlen);
}
memcpy(htmlin + totalbytes, buffer, bytes);
totalbytes += bytes;
*(htmlin + totalbytes) = '\0';
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(htmlparams != NULL && !strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf("\n");
log_printf("%s\n", htmlin);
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
log_printf("SSL_write()\n");
if((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) < 1) {
log_errprintf("%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\n",
procname, c, status, SSL_get_error(ssl, status));
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n", html_get_string(c));
}
}
log_printf("SSL connection using %s\n", htmlsslcipher);
log_printf("dbs_query_vars()\n");
dbs_query_vars();
log_printf("SSL_free()\n");
SSL_free(ssl);
}
html_client()
Kirjoitin samaan tapaan uudestaan myös html_client():in:
static void http_client(int news, struct sockaddr_in sa_cli, int addr_size, char *name) // JariK 2025, 2022
{
int ok;
unsigned char buffer10[10], buffer[512];
int clen = 0;
int reads = 0;
int first = 1, tries = 0;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
while(htmlparams == NULL || clen - strlen(htmlparams) > 0) {
log_printf("read()\n");
if((bytes = read(news, buffer, sizeof(buffer))) < 0) {
log_errprintf("%s: cannot read()\n", procname);
perror("read");
//fflush(stderr);
if(++tries >= 5) {
ok = 0;
break;
}
usleep(1024 * 512 / 5);
continue;
}
reads++;
if(bytes == 0)
break;
if(htmlinlen < totalbytes + bytes + 1) {
htmlinlen = totalbytes + bytes + 1;
htmlin = realloc(htmlin, htmlinlen);
}
memcpy(htmlin + totalbytes, buffer, bytes);
totalbytes += bytes;
*(htmlin + totalbytes) = '\0';
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(htmlparams != NULL && !strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf("\n");
log_printf("%s\n", htmlin);
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(html):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
if((bytes = write(news, html_get_string(c), strlen(html_get_string(c)))) == -1) {
log_errprintf("%s: cannot write() dbs_html[%d]\n", procname, c);
perror("write");
//fflush(stderr);
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n",html_get_string(c));
}
log_printf("\n");
}
log_printf("dbs_query_vars()\n");
dbs_query_vars();
}
Väliaika: uusi pseudosatunnaisuutta arpova funktio pseudorandom_bytes()
Välikkeenä tuli mieleeni uusi näennäissatunnaisuutta muodostava funktio pseudorandom_bytes(). Pseudoressu_bytes() saa satunnaisuuden ressusta, joka tekee kellojonosta “oikeaa satunnaisuutta”. Pseudorandom_bytes() saa satunnaisuuden kellonajoista ja pätkistä kellojonoa. Tuotettava materiaali ressussa on kokonaisuudessaan satunnainen, tässä vähän satunnaisuutta sisältävää materiaalia syötetään sha256 funktioon, ja sha256:lla materiaalista tehdään satunnaista.
Kaksi ensimmäistä funktiota lukevat kelloa, ja palauttavat tarvittavat bitit: pseudorandom_useconds() palauttaa tämän hetken kellonajan ja päiväyksen mikrosekunteina ja pseudorandom_lowusec() palauttaa mikrosekuntien alimmat 8 bittiä.
Pseudorandom_internalbytes() palauttaa avaimen perusteella 32 merkkiä satunnaisuutta. Pseudorandom_topup() lisää avaimeen satunnaisuutta käyttäen alun kello-funktioita.
Pseudorandom_bytes() on varsinainen satunnaisuusfunktio. Se käyttää edellisiä ja muodostaa halutun pituisen satunnaismerkkisarjan.
Pseudorandom_key sisältää avaimen, johon satunnaisuutta lisätään kellojonosta, ja toisaalta käytetään satunnaisbittien arpomiseen.
#define aDEBUG15 2
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);
}
unsigned char pseudorandom_lowusec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec & 0xff);
}
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));
HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
inccvar();
HashFinal(digest, &hash);
memset(&hash, 0, sizeof(hash)); // forget hash
}
#define DEBUG16A 2
#define aDEBUG17 2
#define PSEUDORANDOM_RANDOMNESS_NEEDED 256 // now 125
#define PSEUDORANDOM_MINIMUM_ROUNDS 64 // now 32
static void pseudorandom_topup()
{
int c, d, randomness = 0;
unsigned long long usec;
unsigned char buffer[128];
HashCtx hash;
HashInit(&hash);
HashUpdate(&hash, pseudorandom_key, sizeof(pseudorandom_key)); // include old randomness
HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
inccvar();
for(c = 0; c < PSEUDORANDOM_MINIMUM_ROUNDS ||
randomness < PSEUDORANDOM_RANDOMNESS_NEEDED; c++) {
usec = pseudorandom_useconds();
#ifdef DEBUG16A
fprintf(stdout,"%02d %llx ", c, usec);
#endif
HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
randomness++; // calculate bit for full time
randomness++; // calculate first
memset(&buffer, 0, sizeof(buffer));
for(d = 0; d < sizeof(buffer); d++) {
buffer[d] = pseudorandom_lowusec();
if(d > 0 && buffer[d] != buffer[d - 1])
randomness++; // calculate rest
}
#ifdef DEBUG16A
for(d = 0; d < sizeof(buffer); d++)
fprintf(stdout,"%02x", buffer[d]);
fprintf(stdout,"\n");
fflush(stdout);
#endif
HashUpdate(&hash, (unsigned char *)&buffer, sizeof(buffer));
}
HashFinal(pseudorandom_key, &hash); // save as new key
#ifdef DEBUG16A
fprintf(stdout,"randomness:%d\n", randomness);
#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 DEBUG17
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
}
Seuraavassa lista DEBUG16 testiä: tässä jono, josta pseudorandom_bytes():in satunnaisuus tässä ajossa tulee. Ensimmäinen sarake on rivinumero, toinen sarake on kokonainen kellonaika mikrosekunteineen mikrosekunteina, ja kolmas sarake sisältää 128 näytettä mikrosekuntien alimmasta merkistä.
Tässä ratkaistaan kahta jo ressusta tuttua ongelmaa. Ensimmäisessä yritetään päätellä kuinka paljon satunnaisuutta seuraavassa merkkijonossa on. Tässä on laskettu 1 bitti satunnaisuutta kokonaisesta kellonajasta (alimman mikrosekuntien bitin katsotaan olevan satunnainen). Yksi bitti satunnaisuutta lisätään jokaisesta kolmannen sarakkeen näytesarjasta. Ohjelmassa satunnaisuuden rajaksi katsotaan edellisten sääntöjen mukaan 256 (ennen 125) bittiä. Tässä kellojonon sarjat ovat lyhyitä (hidas kone), joten satunnaisuuden määräksi on saatu 3110 bittiä.
Toisessa ongelmassa yritetään päätellä onko kellojono mahdollista arvata. Tässä uusi versio käy läpi 8 kiloa kellojonoa, ja ressu käy jo ensimmäisellä kierroksella 16 kiloa kellojonoa. Tässä hitaassa koneessa ressukierroksia tehtiin 11, joten ressu on vaikeampi arvattava.
Kolmantena ongelmana voi miettiä ovatko RANDOMNESS_NEEDED ja MINIMUM_ROUNDS tarpeeksi suuria. Randomness needed:in suurentamista rajoittaa tässä hashin koko. Voi aiheuttaa hilpeyttä, jos sanoo tallentavansa 1024 bittiä satunnaisuutta 256 bittiseen puskuriin. Ressussa puskuri on 2048 merkkiä, joten sinne mahtuu satunnaisuutta 16 kilobittiä. Toinen rajoittava tekijä on suoritusaika, ressu suoriutuu kellojonon käsittelystä nopeammin kun sha256. Toisaalta enemmän randomness needed:iä merkitsee vaikeampaa arvattavuutta.
00 63f39ace68616 9d9d9e9e9e9f9f9fa0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a6a7a7a8a8a8a9a9a9aaaaaaababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4b4b4b5b5b5b6b6b7b7b7b8b8b8b9b9babababbbbbbbcbcbcbdbdbebebebfbfbfc0c0c1c1c1c2c2c2c3c3c3c4c4c5c5c5c6c6c6c7c7c7c8c8c9c9c9cacacacbcbcc
01 63f39ace6868d 0e0e0f0f0f1010111111121212131314141415151516161717171818181919191a1a1b1b1b1c1c1c1d1d1e1e1e1f1f1f2020212121222222232324242425252526262727272828282929292a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f30303131313232323333343434353535363637373738383839393a3a3a3b3b3b3c3c3c3d3d
02 63f39ace686d9 5a5a5a5b5b5b5c5c5d5d5d5e5e5e5f5f5f6060616161626262636364646465656566666667676868686969696a6a6a6b6b6c6c6c6d6d6d6e6e6f6f6f707070717171727273737374747475757576767777777878787979797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f808080818182828283838384848485858686868787878888
03 63f39ace68723 a6a6a7a7a8a8a8a9a9a9aaaaaaababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4b4b4b5b5b5b6b6b7b7b7b8b8b8b9b9babababbbbbbbcbcbcbdbdbebebebfbfbfc0c0c0c1c1c2c2c2c3c3c3c4c4c4c5c5c6c6c6c7c7c7c8c8c9c9c9cacacacbcbcbcccccdcdcdcecececfcfcfd0d0d1d1d1d2d2d2d3d3d4d4d4d5
04 63f39ace6876f f0f0f1f1f1f2f2f2f3f3f4f4f4f5f5f5f6f6f6f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfdfefeffffff0000000101010202030303040404050506060607070708080809090a0a0a0b0b0b0c0c0c0d0d0e0e0e0f0f0f1010101111121212131313141415151516161617171718181919191a1a1a1b1b1b1c1c1d1d1d1e1e1e
05 63f39ace687ba 3b3b3c3c3c3d3d3d3e3e3e3f3f404040414141424242434344444445454546464647474848484949494a4a4b4b4b4c4c4c4d4d4d4e4e4f4f4f5050505151515252535353545454555556565657575758585859595a5a5a5b5b5b5c5c5c5d5d5e5e5e5f5f5f606061616162626263636364646565656666666767676868696969
06 63f39ace68803 8485858586868687878888888989898a8a8a8b8b8c8c8c8d8d8d8e8e8f8f8f9090909191919292939393949494959595969697979798989899999a9a9a9b9b9b9c9c9c9d9d9e9e9e9f9f9fa0a0a0a1a1a2a2a2a3a3a3a4a4a5a5a5a6a6a6a7a7a7a8a8a9a9a9aaaaaaabababacacadadadaeaeaeafafafb0b0b1b1b1b2b2b2b3
07 63f39ace6884d cececfcfcfd0d0d0d1d1d1d2d2d3d3d3d4d4d4d5d5d6d6d6d7d7d7d8d8d8d9d9dadadadbdbdbdcdcdcdddddedededfdfdfe0e0e1e1e1e2e2e2e3e3e3e4e4e5e5e5e6e6e6e7e7e7e8e8e9e9e9eaeaeaebebecececedededeeeeeeefeff0f0f0f1f1f1f2f2f2f3f3f4f4f4f5f5f5f6f6f6f7f7f8f8f8f9f9f9fafafbfbfbfcfcfc
08 63f39ace68897 1818181919191a1a1a1b1b1c1c1c1d1d1d1e1e1f1f1f2020202121212222232323242424252525262627272728282829292a2a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f3030303131323232333333343435353536363637373738383939393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f3f404041414142424243434444444545454646
09 63f39ace688e0 6161626262636364646465656566666667676868686969696a6a6a6b6b6c6c6c6d6d6d6e6e6e6f6f707070717171727273737374747475757576767777777878787979797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f8080808181828282838383848484858586868687878788888989898a8a8a8b8b8b8c8c8d8d8d8e8e8e8f8f8f
10 63f39ace6892a abababacacacadadadaeaeafafafb0b0b0b1b1b2b2b2b3b3b3b4b4b4b5b5b6b6b6b7b7b7b8b8b8b9b9babababbbbbbbcbcbcbdbdbebebebfbfbfc0c0c1c1c1c2c2c2c3c3c3c4c4c5c5c5c6c6c6c7c7c7c8c8c9c9c9cacacacbcbcccccccdcdcdcecececfcfd0d0d0d1d1d1d2d2d2d3d3d4d4d4d5d5d5d6d6d7d7d7d8d8d8d9d9
11 63f39ace68973 f6f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfdfefeffffff0000000101010202030303040404050506060607070708080809090a0a0a0b0b0b0c0c0c0d0d0e0e0e0f0f0f1010111111121212131313141415151516161617171718181919191a1a1a1b1b1c1c1c1d1d1d1e1e1e1f1f20202021212122222223232424242525
12 63f39ace689c0 41424242434343444444454546464647474748484949494a4a4a4b4b4b4c4c4d4d4d4e4e4e4f4f4f5050515151525252535353545455555556565657575858585959595a5a5a5b5b5c5c5c5d5d5d5e5e5e5f5f606060616161626263636364646465656566666767676868686969696a6a6b6b6b6c6c6c6d6d6e6e6e6f6f6f70
13 63f39ace68a0a 8b8b8b8c8c8c8d8d8e8e8e8f8f8f9090909191929292939393949495959596969697979798989999999a9a9a9b9b9b9c9c9d9d9d9e9e9e9f9fa0a0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a6a7a7a8a8a8a9a9a9aaaaabababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4b4b4b5b5b5b6b6b7b7b7b8b8b8b9b9
14 63f39ace68a53 d4d5d5d5d6d6d6d7d7d8d8d8d9d9d9dadadadbdbdcdcdcdddddddedededfdfe0e0e0e1e1e1e2e2e3e3e3e4e4e4e5e5e5e6e6e7e7e7e8e8e8e9e9e9eaeaebebebecececededeeeeeeefefeff0f0f0f1f1f2f2f2f3f3f3f4f4f4f5f5f6f6f6f7f7f7f8f8f8f9f9fafafafbfbfbfcfcfdfdfdfefefeffffff000001010102020203
15 63f39ace68aa1 22222323242424252525262627272728282829292a2a2a2b2b2b2c2c2d2d2d2e2e2e2f2f3030303131313232323333343434353535363637373738383839393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f4040404141414242424343444444454545464647474748484849494a4a4a4b4b4b4c4c4d4d4d4e4e4e4f4f505050515151
16 63f39ace68aec 6d6d6d6e6e6e6f6f6f7070717171727272737374747475757576767677777878787979797a7a7a7b7b7c7c7c7d7d7d7e7e7f7f7f8080808181818282838383848484858585868687878788888889898a8a8a8b8b8b8c8c8c8d8d8e8e8e8f8f8f9090909191929292939393949494959596969697979798989999999a9a9a9b9b
17 63f39ace68b35 b6b6b7b7b8b8b8b9b9b9babababbbbbcbcbcbdbdbdbebebebfbfc0c0c0c1c1c1c2c2c3c3c3c4c4c4c5c5c5c6c6c7c7c7c8c8c8c9c9c9cacacbcbcbcccccccdcdcecececfcfcfd0d0d0d1d1d2d2d2d3d3d3d4d4d4d5d5d6d6d6d7d7d7d8d8d8d9d9dadadadbdbdbdcdcdddddddedededfdfdfe0e0e1e1e1e2e2e2e3e3e3e4e4e5
18 63f39ace68b7f 000000010101020202030304040405050506060607070808080909090a0a0b0b0b0c0c0c0d0d0d0e0e0f0f0f1010101111111212131313141414151516161617171718181819191a1a1a1b1b1b1c1c1c1d1d1e1e1e1f1f1f2020212121222222232323242425252526262627272728282929292a2a2a2b2b2b2c2c2d2d2d2e2e
19 63f39ace68bc9 4c4d4d4d4e4e4e4f4f505050515151525252535354545455555556565757575858585959595a5a5b5b5b5c5c5c5d5d5d5e5e5f5f5f6060606161626262636363646464656566666667676768686869696a6a6a6b6b6b6c6c6d6d6d6e6e6e6f6f6f7070717171727272737373747475757576767677777778787979797a7a7a7b
20 63f39ace68c15 96969697979798989999999a9a9a9b9b9b9c9c9d9d9d9e9e9e9f9fa0a0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a6a7a7a8a8a8a9a9a9aaaaabababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4b4b4b5b5b6b6b6b7b7b7b8b8b8b9b9babababbbbbbbcbcbcbdbdbebebebfbfbfc0c0c0c1c1c2c2c2c3c3c3c4c4
21 63f39ace68c5e dfdfe0e0e1e1e1e2e2e2e3e3e3e4e4e5e5e5e6e6e6e7e7e7e8e8e9e9e9eaeaeaebebecececedededeeeeeeefeff0f0f0f1f1f1f2f2f2f3f3f4f4f4f5f5f5f6f6f7f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfdfefeffffff0000000101020202030303040404050506060607070708080809090a0a0a0b0b0b0c0c0c0d0d0e
22 63f39ace68ca9 292a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f3030303131323232333333343434353536363637373738383939393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f3f4040414141424242434344444445454546464647474848484949494a4a4a4b4b4c4c4c4d4d4d4e4e4e4f4f505050515151525253535354545455555556565757575858
23 63f39ace68cf2 7373747474757576767677777778787979797a7a7a7b7b7b7c7c7d7d7d7e7e7e7f7f7f8080818181828282838383848485858586868687878888888989898a8a8a8b8b8c8c8c8d8d8d8e8e8e8f8f909090919191929293939394949495959596969797979898989999999a9a9b9b9b9c9c9c9d9d9e9e9e9f9f9fa0a0a0a1a1a2
24 63f39ace68d3c bcbdbdbebebebfbfbfc0c0c1c1c1c2c2c2c3c3c3c4c4c5c5c5c6c6c6c7c7c8c8c8c9c9c9cacacacbcbcccccccdcdcdcecececfcfd0d0d0d1d1d1d2d2d2d3d3d4d4d4d5d5d5d6d6d7d7d7d8d8d8d9d9d9dadadbdbdbdcdcdcdddddddededfdfdfe0e0e0e1e1e2e2e2e3e3e3e4e4e4e5e5e6e6e6e7e7e7e8e8e8e9e9eaeaeaebeb
25 63f39ace68d85 060607070708080909090a0a0a0b0b0b0c0c0d0d0d0e0e0e0f0f0f1010111111121212131313141415151516161617171818181919191a1a1a1b1b1c1c1c1d1d1d1e1e1e1f1f202020212121222223232324242425252526262727272828282929292a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f3030303131323232333333343434
26 63f39ace68dcf 50505151525252535353545454555556565657575758585859595a5a5a5b5b5b5c5c5d5d5d5e5e5e5f5f5f6060616161626262636363646465656566666667676768686969696a6a6a6b6b6c6c6c6d6d6d6e6e6e6f6f707070717171727272737374747475757576767777777878787979797a7a7b7b7b7c7c7c7d7d7d7e7e7f
27 63f39ace68e19 9c9c9c9d9d9e9e9e9f9f9fa0a0a1a1a1a2a2a2a3a3a3a4a4a5a5a5a6a6a6a7a7a7a8a8a9a9a9aaaaaaababacacacadadadaeaeaeafafb0b0b0b1b1b1b2b2b2b3b3b4b4b4b5b5b5b6b6b6b7b7b8b8b8b9b9b9bababbbbbbbcbcbcbdbdbdbebebfbfbfc0c0c0c1c1c1c2c2c3c3c3c4c4c4c5c5c6c6c6c7c7c7c8c8c8c9c9cacaca
28 63f39ace68e64 e5e5e6e6e6e7e7e8e8e8e9e9e9eaeaebebebecececedededeeeeefefeff0f0f0f1f1f1f2f2f3f3f3f4f4f4f5f5f6f6f6f7f7f7f8f8f8f9f9fafafafbfbfbfcfcfcfdfdfefefeffffff0000000101020202030303040405050506060607070708080909090a0a0a0b0b0b0c0c0d0d0d0e0e0e0f0f101010111111121212131314
29 63f39ace68eaf 303030313131323233333334343435353536363737373838383939393a3a3b3b3b3c3c3c3d3d3e3e3e3f3f3f4040404141424242434343444444454546464647474748484949494a4a4a4b4b4b4c4c4d4d4d4e4e4e4f4f4f5050515151525252535353545455555556565657575858585959595a5a5a5b5b5c5c5c5d5d5d5e5e
30 63f39ace68efb 7c7c7c7d7d7e7e7e7f7f7f80808181818282828383848484858585868687878788888889898a8a8a8b8b8b8c8c8c8d8d8e8e8e8f8f8f90909191919292929393949494959595969697979798989899999a9a9a9b9b9b9c9c9c9d9d9e9e9e9f9f9fa0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a7a7a7a8a8a8a9a9aaaaaaabab
31 63f39ace68f46 c6c7c7c7c8c8c9c9c9cacacacbcbcbcccccdcdcdcecececfcfd0d0d0d1d1d1d2d2d2d3d3d4d4d4d5d5d5d6d6d6d7d7d8d8d8d9d9d9dadadbdbdbdcdcdcdddddddededfdfdfe0e0e0e1e1e1e2e2e3e3e3e4e4e4e5e5e6e6e6e7e7e7e8e8e8e9e9eaeaeaebebebecececededeeeeeeefefeff0f0f0f1f1f2f2f2f3f3f3f4f4f5f5
32 63f39ace68f8f 10111111121212131313141415151516161617171718181919191a1a1a1b1b1b1c1c1d1d1d1e1e1e1f1f202020212121222222232324242425252526262727272828282929292a2a2b2b2b2c2c2c2d2d2d2e2e2f2f2f3030303131323232333333343434353536363637373738383839393a3a3a3b3b3b3c3c3c3d3d3e3e3e3f
33 63f39ace68fd9 5a5a5b5b5b5c5c5d5d5d5e5e5e5f5f5f6060616161626262636364646465656566666667676868686969696a6a6a6b6b6c6c6c6d6d6d6e6e6e6f6f707070717171727273737374747475757576767777777878787979797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f80808081818282828383838484848585868686878787888889
34 63f39ace69023 a4a4a4a5a5a6a6a6a7a7a7a8a8a8a9a9aaaaaaabababacacacadadaeaeaeafafafb0b0b1b1b1b2b2b2b3b3b3b4b4b5b5b5b6b6b6b7b7b7b8b8b9b9b9babababbbbbcbcbcbdbdbdbebebebfbfc0c0c0c1c1c1c2c2c2c3c3c4c4c4c5c5c5c6c6c6c7c7c8c8c8c9c9c9cacacbcbcbcccccccdcdcdcececfcfcfd0d0d0d1d1d1d2d2
35 63f39ace6906d f0f0f0f1f1f1f2f2f3f3f3f4f4f4f5f5f5f6f6f7f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfefefeffffff0000000101020202030303040404050506060607070708080909090a0a0a0b0b0b0c0c0d0d0d0e0e0e0f0f0f1010111111121212131313141415151516161617171818181919191a1a1a1b1b1c1c1c1d1d1d1e1e
36 63f39ace690ba 3a3b3b3c3c3c3d3d3d3e3e3e3f3f404040414141424243434344444445454546464747474848484949494a4a4b4b4b4c4c4c4d4d4d4e4e4f4f4f5050505151525252535353545454555556565657575758585859595a5a5a5b5b5b5c5c5d5d5d5e5e5e5f5f5f6060616161626262636363646465656566666667676868686969
37 63f39ace69103 8485858586868687878888888989898a8a8a8b8b8c8c8c8d8d8d8e8e8e8f8f909090919191929292939394949495959596969797979898989999999a9a9b9b9b9c9c9c9d9d9d9e9e9f9f9fa0a0a0a1a1a2a2a2a3a3a3a4a4a4a5a5a6a6a6a7a7a7a8a8a8a9a9aaaaaaabababacacadadadaeaeaeafafafb0b0b1b1b1b2b2b2b3
38 63f39ace6914d cececfcfcfd0d0d0d1d1d2d2d2d3d3d3d4d4d4d5d5d6d6d6d7d7d7d8d8d9d9d9dadadadbdbdbdcdcdddddddedededfdfdfe0e0e1e1e1e2e2e2e3e3e4e4e4e5e5e5e6e6e6e7e7e8e8e8e9e9e9eaeaeaebebecececedededeeeeefefeff0f0f0f1f1f1f2f2f3f3f3f4f4f4f5f5f5f6f6f7f7f7f8f8f8f9f9f9fafafbfbfbfcfcfc
39 63f39ace69197 1818181919191a1a1a1b1b1c1c1c1d1d1d1e1e1f1f1f2020202121212222232323242424252525262627272728282829292a2a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f3030303131323232333333343435353536363637373738383939393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f3f404041414142424243434444444545454646
40 63f39ace691e0 61626262636363646464656566666667676768686869696a6a6a6b6b6b6c6c6d6d6d6e6e6e6f6f6f7070717171727272737373747475757576767677777878787979797a7a7a7b7b7c7c7c7d7d7d7e7e7e7f7f808080818181828282838384848485858586868787878888888989898a8a8b8b8b8c8c8c8d8d8d8e8e8f8f8f90
41 63f39ace6922a abababacacadadadaeaeaeafafb0b0b0b1b1b1b2b2b2b3b3b4b4b4b5b5b5b6b6b6b7b7b8b8b8b9b9b9bababbbbbbbcbcbcbdbdbdbebebfbfbfc0c0c0c1c1c1c2c2c3c3c3c4c4c4c5c5c5c6c6c7c7c7c8c8c8c9c9cacacacbcbcbcccccccdcdcecececfcfcfd0d0d0d1d1d2d2d2d3d3d3d4d4d5d5d5d6d6d6d7d7d7d8d8d9d9d9
42 63f39ace69274 f4f5f5f6f6f6f7f7f7f8f8f8f9f9fafafafbfbfbfcfcfdfdfdfefefeffffff0000010101020202030303040405050506060607070708080909090a0a0a0b0b0c0c0c0d0d0d0e0e0e0f0f101010111111121212131314141415151516161717171818181919191a1a1b1b1b1c1c1c1d1d1d1e1e1f1f1f20202021212222222323
43 63f39ace692be 424242434343444444454546464647474748484849494a4a4a4b4b4b4c4c4c4d4d4e4e4e4f4f4f5050515151525252535353545455555556565657575758585959595a5a5a5b5b5c5c5c5d5d5d5e5e5e5f5f606060616161626262636364646465656566666767676868686969696a6a6b6b6b6c6c6c6d6d6d6e6e6f6f6f7070
44 63f39ace6930a 8b8c8c8c8d8d8d8e8e8e8f8f909090919191929293939394949495959596969797979898989999999a9a9b9b9b9c9c9c9d9d9e9e9e9f9f9fa0a0a0a1a1a2a2a2a3a3a3a4a4a4a5a5a6a6a6a7a7a7a8a8a8a9a9aaaaaaabababacacadadadaeaeaeafafafb0b0b1b1b1b2b2b2b3b3b3b4b4b5b5b5b6b6b6b7b7b8b8b8b9b9b9ba
45 63f39ace69357 d8d8d8d9d9d9dadadadbdbdcdcdcdddddddededfdfdfe0e0e0e1e1e2e2e2e3e3e3e4e4e5e5e5e6e6e6e7e7e8e8e8e9e9e9eaeaeaebebecececedededeeeeefefeff0f0f0f1f1f2f2f2f3f3f3f4f4f5f5f5f6f6f6f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfdfefeffffff0000000101020202030303040405050506060607
46 63f39ace693a2 22232324242425252526262727272828282929292a2a2b2b2b2c2c2c2d2d2d2e2e2f2f2f3030303131323232333333343434353536363637373738383839393a3a3a3b3b3b3c3c3c3d3d3e3e3e3f3f3f4040414141424242434343444445454546464647474748484949494a4a4a4b4b4c4c4c4d4d4d4e4e4e4f4f5050505151
47 63f39ace693eb 6c6c6d6d6d6e6e6f6f6f7070707171717272737373747474757575767677777778787879797a7a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f8080808181828282838383848485858586868687878788888989898a8a8a8b8b8b8c8c8d8d8d8e8e8e8f8f8f90909191919292929399999a9a9b9b9b9c9c9c9d9d9e9e9e9f9f9fa0a0a0
48 63f39ace6943d bebebebfbfbfc0c0c1c1c1c2c2c2c3c3c4c4c4c5c5c5c6c6c6c7c7c8c8c8c9c9c9cacacacbcbcccccccdcdcdcececfcfcfd0d0d0d1d1d1d2d2d3d3d3d4d4d4d5d5d5d6d6d7d7d7d8d8d8d9d9d9dadadbdbdbdcdcdcdddddedededfdfdfe0e0e0e1e1e2e2e2e3e3e3e4e4e4e5e5e6e6e6e7e7e7e8e8e9e9e9eaeaeaebebebecec
49 63f39ace69487 0708080809090a0a0a0b0b0b0c0c0c0d0d0e0e0e0f0f0f1010101111121212131313141414151516161617171718181919191a1a1a1b1b1b1c1c1d1d1d1e1e1e1f1f1f2020212121222222232324242425252526262627272828282929292a2a2a2b2b2c2c2c2d2d2d2e2e2f2f2f303030313131323233333334343435353536
50 63f39ace694d1 515252535353545454555556565657575758585859595a5a5a5b5b5b5c5c5d5d5d5e5e5e5f5f5f6060616161626262636363646465656566666667676768686969696a6a6a6b6b6c6c6c6d6d6d6e6e6e6f6f707070717171727272737374747475757576767777777878787979797a7a7b7b7b7c7c7c7d7d7d7e7e7f7f7f8080
51 63f39ace6951a 9d9e9e9e9f9f9fa0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a6a7a7a8a8a8a9a9a9aaaaaaababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4b4b4b5b5b5b6b6b7b7b7b8b8b8b9b9babababbbbbbbcbcbcbdbdbebebebfbfbfc0c0c0c1c1c2c2c2c3c3c3c4c4c4c5c5c6c6c6c7c7c7c8c8c9c9c9cacacacbcbcbcc
52 63f39ace69566 e7e7e8e8e8e9e9e9eaeaebebebecececededeeeeeeefefeff0f0f0f1f1f2f2f2f3f3f3f4f4f4f5f5f6f6f6f7f7f7f8f8f8f9f9fafafafbfbfbfcfcfdfdfdfefefeffffff0000010101020202030303040405050506060607070808080909090a0a0a0b0b0c0c0c0d0d0d0e0e0e0f0f1010101111111212121313141414151515
53 63f39ace695b1 313232333333343434353536363637373738383839393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f3f4040414141424242434343444445454546464647474848484949494a4a4a4b4b4c4c4c4d4d4d4e4e4e4f4f505050515151525252535354545455555556565757575858585959595a5a5b5b5b5c5c5c5d5d5d5e5e5f5f5f6060
54 63f39ace695fa 7b7b7c7c7c7d7d7d7e7e7f7f7f8080808181828282838383848484858586868687878788888889898a8a8a8b8b8b8c8c8d8d8d8e8e8e8f8f909090919191929292939394949495959596969797979898989999999a9a9b9b9b9c9c9c9d9d9d9e9e9f9f9fa0a0a0a1a1a2a2a2a3a3a3a4a4a4a5a5a6a6a6a7a7a7a8a8a8a9a9aa
55 63f39ace69644 c5c5c5c6c6c7c7c7c8c8c8c9c9c9cacacbcbcbcccccccdcdcecececfcfcfd0d0d0d1d1d2d2d2d3d3d3d4d4d4d5d5d6d6d6d7d7d7d8d8d9d9d9dadadadbdbdbdcdcdddddddedededfdfdfe0e0e1e1e1e2e2e2e3e3e3e4e4e5e5e5e6e6e6e7e7e8e8e8e9e9e9eaeaeaebebecececedededeeeeeeefeff0f0f0f1f1f1f2f2f3f3f3
56 63f39ace6968d 0e0f0f0f1010101111121212131313141414151516161617171718181919191a1a1a1b1b1b1c1c1d1d1d1e1e1e1f1f1f2020212121222222232323242425252526262627272828282929292a2a2a2b2b2c2c2c2d2d2d2e2e2e2f2f303030313131323233333334343435353536363737373838383939393a3a3b3b3b3c3c3c3d
57 63f39ace696d7 58585959595a5a5a5b5b5c5c5c5d5d5d5e5e5e5f5f606060616161626263636364646465656566666767676868686969696a6a6b6b6b6c6c6c6d6d6d6e6e6f6f6f7070707171727272737373747474757576767677777778787879797a7a7a7b7b7b7c7c7d7d7d7e7e7e7f7f7f80808181818282828383838484858585868686
58 63f39ace69720 a1a2a2a2a3a3a3a4a4a5a5a5a6a6a6a7a7a7a8a8a9a9a9aaaaaaababacacacadadadaeaeaeafafb0b0b0b1b1b1b2b2b2b3b3b4b4b4b5b5b5b6b6b6b7b7b8b8b8b9b9b9bababbbbbbbcbcbcbdbdbdbebebfbfbfc0c0c0c1c1c1c2c2c3c3c3c4c4c4c5c5c6c6c6c7c7c7c8c8c8c9c9cacacacbcbcbcccccccdcdcecececfcfcfd0
59 63f39ace6976a ededeeeeeeefeff0f0f0f1f1f1f2f2f2f3f3f4f4f4f5f5f5f6f6f6f7f7f8f8f8f9f9f9fafafbfbfbfcfcfcfdfdfdfefeffffff0000000101010202030303040404050506060607070708080809090a0a0a0b0b0b0c0c0c0d0d0e0e0e0f0f0f1010111111121212131313141415151516161617171718181919191a1a1a1b1b1b
60 63f39ace697ba 3b3b3c3c3c3d3d3d3e3e3f3f3f4040404141424242434343444445454546464647474748484949494a4a4a4b4b4c4c4c4d4d4d4e4e4f4f4f5050505151525252535353545455555556565657575758585959595a5a5a5b5b5c5c5c5d5d5d5e5e5f5f5f6060606161626262636363646465656566666667676768686969696a6a
61 63f39ace69804 8586868687878788888889898a8a8a8b8b8b8c8c8c8d8d8e8e8e8f8f8f9090919191929292939393949495959596969697979798989999999a9a9a9b9b9c9c9c9d9d9d9e9e9e9f9fa0a0a0a1a1a1a2a2a2a3a3a4a4a4a5a5a5a6a6a7a7a7a8a8a8a9a9a9aaaaabababacacacadadadaeaeafafafb0b0b0b1b1b1b2b2b3b3b3b4
62 63f39ace6984e cfcfcfd0d0d1d1d1d2d2d2d3d3d3d4d4d5d5d5d6d6d6d7d7d7d8d8d9d9d9dadadadbdbdcdcdcdddddddedededfdfe0e0e0e1e1e1e2e2e2e3e3e4e4e4e5e5e5e6e6e7e7e7e8e8e8e9e9e9eaeaebebebecececedededeeeeefefeff0f0f0f1f1f1f2f2f3f3f3f4f4f4f5f5f6f6f6f7f7f7f8f8f8f9f9fafafafbfbfbfcfcfcfdfd
63 63f39ace69897 181919191a1a1a1b1b1c1c1c1d1d1d1e1e1e1f1f202020212121222223232324242425252526262727272828282929292a2a2b2b2b2c2c2c2d2d2e2e2e2f2f2f3030303131323232333333343434353536363637373738383939393a3a3a3b3b3b3c3c3d3d3d3e3e3e3f3f3f4040414141424242434343444445454546464647
randomness:3110
Tässä vielä –dieharder testilista kolmen gigan kokoisella tiedostolla: Tuloksena vain yksi weak, ei yhtään failed:ia. Huomaa että jostain syystä sha256:t eivät täsmää kirjoitetussa tiedostossa.. (raspberry pi 500 + sd)
$ ./newressu --pseudorandom --sample --dieharder
blocksize:393216(384K), blocks:8192(8K), filesize:3221225472(3G)
./newressu: sample(): writing file, filename:newressusample28.rnd
mbinblocks:2
wrote 3.00GB, 7.22MB/sec, took 07m // ||||// |||| ---
./newressu: sample(): hashing file, filename:newressusample28.rnd, hashfilename:newressusample28.rnd.sha256, sha256:42eaf96585934b1ec4fd3b1b862d6781843548592550d44944e0c7fc02a69c99
./newressu: sample(): checking sha256, filename:newressusample28.rnd, command:'sha256sum newressusample28.rnd'
dd06b21bf93160ce1806e6206db001a730f46c1b7d10af580c8fadd4c66df4d9 newressusample28.rnd
./newressu: sample(): running dieharder "dieharder -a -g 201 -f newressusample28.rnd > newressusample28.rnd.dieharder 2>&1"
./newressu: sample(): grepping dieharder problems "grep "WEAK\|FAILED" newressusample28.rnd.dieharder"
diehard_2dsphere| 2| 8000| 100|0.99995105| WEAK
./newressu: sample(): calculating WEAK lines, lines = 1, "grep WEAK newressusample28.rnd.dieharder"
./newressu: sample(): calculating FAILED lines, lines = 0, "grep FAILED newressusample28.rnd.dieharder"
./newressu: sample(): grepping last rewound count "grep rewound newressusample28.rnd.dieharder | tail -n1"
# The file file_input_raw was rewound 114 times
./newressu: sample(): removing file newressusample28.rnd
$
Vielä läppärillä ajetut dieharder testit (näissä sha256:t täsmäsivät):
'input' = "pseudorandom", 'filesize' = "500m", 'filename' = "newressusample2713.rnd", 'weak' = "9", 'failed' = "1"
'input' = "pseudorandom", 'filesize' = "600m", 'filename' = "newressusample2714.rnd", 'weak' = "4", 'failed' = "1"
'input' = "pseudorandom", 'filesize' = "700m", 'filename' = "newressusample2715.rnd", 'weak' = "2", 'failed' = "2"
'input' = "pseudorandom", 'filesize' = "800m", 'filename' = "newressusample2716.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "900m", 'filename' = "newressusample2717.rnd", 'weak' = "2", 'failed' = "1"
'input' = "pseudorandom", 'filesize' = "1g", 'filename' = "newressusample2718.rnd", 'weak' = "6", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g100m", 'filename' = "newressusample2719.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g200m", 'filename' = "newressusample2720.rnd", 'weak' = "4", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g300m", 'filename' = "newressusample2721.rnd", 'weak' = "4", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g400m", 'filename' = "newressusample2722.rnd", 'weak' = "4", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g500m", 'filename' = "newressusample2723.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g600m", 'filename' = "newressusample2724.rnd", 'weak' = "2", 'failed' = "1"
'input' = "pseudorandom", 'filesize' = "1g700m", 'filename' = "newressusample2725.rnd", 'weak' = "7", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g800m", 'filename' = "newressusample2726.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "1g900m", 'filename' = "newressusample2727.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "2g", 'filename' = "newressusample2728.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "3g", 'filename' = "newressusample2729.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "4g", 'filename' = "newressusample2730.rnd", 'weak' = "0", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "5g", 'filename' = "newressusample2731.rnd", 'weak' = "6", 'failed' = "0"
'input' = "pseudorandom", 'filesize' = "6g", 'filename' = "newressusample2732.rnd", 'weak' = "5", 'failed' = "0"
En malttanut olla kokeilematta miltä näyttäisi, jos topup rivin tekisi ressulla. Se on kuitenkin sen verran erilainen toimintatapa, että päätin tehdä tästä ressuversiosta toisen näytöksen. Tässä ressua käyttävä pseudorandom lähdekoodi:
#define aDEBUG15 2
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_lowusec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec & 0xff);
}
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));
HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
inccvar();
HashFinal(digest, &hash);
memset(&hash, 0, sizeof(hash)); // forget hash
}
static int randomness = 0;
#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )
static void pseudorandom_ressuround(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 = pseudorandom_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;
}
}
}
#define DEBUG16A 2
#define aDEBUG17 2
#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 = 0;
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)); // include old randomness
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();
#ifdef DEBUG16A
fprintf(stdout,"%02d %llx ", c, usec);
#endif
HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
randomness++; // calculate bit for full time
pseudorandom_ressuround(sizeof(buffer), buffer);
clocksused += (sizeof(buffer) * 8);
#ifdef DEBUG16A
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 DEBUG16A
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 DEBUG17
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
}
Tässä topup lista DEBUG16:lla. Tässä kolmas sarake on muodostettu ressulla, ja se näyttää jo valmiiksi ihan hyvältä satunnaisuudelta.
00 63f4e6cee66a1 a6f68699fa49690a28651700043879ebc858d0cda539fe19b9442adf5445e1b493e37a3a11fb1a7e976117c3027abae164355f04c244b3f7ac19201ab846352a492af825ffc148dacb44a809ae3458db66dd88aedacba7394e8457a2f146dcc81fa82005bce06779b17cb138faeb89321a4d5c09576d916be36b8a9581a0c9ac
01 63f4e6cee687e d74ac6bc0d27cc36707d37564730e26febdaff6876953b5436a5e18133809c145ca174e1fbfa81676888703f1b0f84498286dfd423c2595fe3cab228cb30a690e0e9df46a847b782f5ddfe7c93940486811c605add2f923a11c917b8892977fa26bd5a2e11fc95b27bbde0543a545fddb3b2d35af71451d23fa94b70506054eb
02 63f4e6cee6a39 b3c3c416c2baa7e0eef7214ddebb8cf8a40756601a1178ed90f563f824b74b202764003b5b887c56d9a8fec743a3a911303e849711c2acb6a3a9b1d0e20e429ecaa0a1c7b3d764064047b03e34a5ae2d504209fb21358c6592f63969a676120d17b122e4501e7e6d0739d808d4e0697ca8befe9de9951a181e06be8d1b295a86
03 63f4e6cee6be9 2d1eb50fc54a468189b8f7049df010ee81aba4ce8e6db29ee4615eb6b15f5a2657be3652dd81cc66102b7cdda5a8a18a8f8bcc9d4460dbe0f93c40e0561fd85c9f3f7308af08dc55e447008045b9b0cac149dc8590b3a18af358d25e41e976b94421813740a16a560a5643651413cb47159b527a00b312b4dc6888e1206c0e2a
04 63f4e6cee6d9b 051af40947eb7ba5037262dc40935f3d7f02f2c25e775644e2aebdacf4865c90731fe072a0ce8a0e2aeaeeb6ef28c96997c80de00ff3375d51cb1fea375935422a21e50df950f5ed5f52236059c4036679c8f037c98f43eb3ab9f90eb5cbb879ae5f087b456f40bdbbfa3633464bd326d1afbec167b9a199c2a036690cffa7dd
05 63f4e6cee6f4a c535207d0d133e2c930037944edbbeb956e0917cf152139f3dbede36be0fdf17dc76a568662b0b90b50643276dbe31b5abbdae37c1ef2f5a3b45e5e35fca4d2acc6aefcfa31d7f26d4e8ee4b5cbbc705ee3932f43e25f89079e57da973da1161972db8edc826cfeb19639653b4e5026cead6db0d815f5f5ddc0946ac66e4c790
06 63f4e6cee70fa fbaf9286688dbd94a5b5067d406b290d488f5cf0449c29fcb8f05cad9ff2919d651f57d66363ee5876b9819220e2d40f4af45353dabf5179bd585df010f26fcbd82f9b4cf38a64233759a6efe476c0db702324fc64f7b2a89f09499b5a5fd850282a298806da7bb47d150dd4195f95393c8aea0ece4035bbc67b546cbfd8622f
07 63f4e6cee72cb b8027450001266641961f04b08926937092e81f0fdfae49797e2b2599626e77d85712fd8c327cbf8ab376dc4eaa8b512d0fc78bad8c90221eb9fd858019d15c9092535f06a781529ce3b9f96431a552f34627a4d8d66d52de01015752de285f2c97781e0b9e96d1ac3f8d5daa56a85054bebff652ce70584737b1d74b58d37ae
08 63f4e6cee747b 01da9853f8db51300d0141a2c7b26e443b7757d4305b2385fb0a218d1f961a2961e9accfc304d28b019f220f242ffe4d186fdc7801b83ef7d39cbcb99636de54b6a2bcebfc8c377b4a08e2b3738aa8094ef504faaa6fcc26f1e196c0fe4048abe7535555121bbe2cbfd37ec9707cf2737c4a6182c26fd94f679baca31a3ca4d4
09 63f4e6cee762a dd4f7daf14fba5ea7a92cd27ac54b87e2d2f4ea56edf02c590b9223e379063f0dfa333195c714369804a43dba9aa423c65896267cde7dac11111a9fea70cbbff9aa95b60879c983e46cfd40cbcd512e1e14fad0c201f283d57b308e50334a7ccafc880ccab8549ebd0e325009f1d6146f17bb29eb746c9abbab01a4e8d4abe3b
10 63f4e6cee77d8 623a0175156764d064b2fae49bab787bdd0760250c2c4338a49f646ab6f36289630113533c77bd0c06c4885b0b6abc422f181348ccbdc84acb7777d2904c0930b26fd9acbb8929e15533cb181e70fb7e6e6d7847b9cf448a9c0dcecde8aba3c7f0d7c3c943efe0100b02ecfa9abc7b60c18041934b77bcdc1aed84173cf90488
11 63f4e6cee7987 6aaf9fb95bdd8f4a72ff719664241ec5dd74acf88f4629f35c243c0ab45ddf62b809528ff7a6bd353989bd76423e204cc45c59d1bfb2483548e49fdd4c4023714d4803963e089c7a30bbefbf628cfcf8b8bf376da7be46c043755a1ef58237bb57c06902c0ea0f8db80b9640296332c2bc25cdef7077e3902c9de3660b1dcef7
12 63f4e6cee7b37 5473cb163b217ce0da8cf1b0557e4435109dfd157ff6269230aca932c6c3cfb6da6527aa367c988babd4715699d1575caa9a11562da96ef0ba1b70499e835dad8c3bd0c8b5a5d3f76b0026132091ea32f1ba9b22a05659d4052e6e485ba4a69069e5d69ea50dfdf87859429208e697a316d51a30934e47d5ac04b95e4d34b88e
13 63f4e6cee7ce6 d65e9256a187a7093e802a76a444122764c7066b15ea804cea6f41c56484434a842ffedd9273d58c018d0cb1af50f9f7faacef60482469b90d1e8dc3bc1a41856a817c1cf23c93041cbad65e13bc1827d2cf0d68470f4d4b0adcde2e604c5d74d8554238792bb2162d6dde858584b5122ef8ec2b9606b5f220a1f3ec5a8cbe11
14 63f4e6cee7e94 e4ce00940decdc580e087111add1986285114e267b8199dbbdc7017decfe3340370199873ccb1b9a2f01c99313233e5d410a5605ca6376a2bdf01fdd1c4fd9e1a07ef892272f929ad03730a7a0155b917538d26bf07dba22fab8650fa7da055e70c05070ecafec3b604a5ec60d768033c43bdebfb0fb3f86ecdb94f2f041fcb7
15 63f4e6cee8047 ab1dcf2dc63486df585500db61d9c0553b0c8d2ccff457be3c21fbe61153c092d6123729b6671220a49d1052002037f59fb3663335fe5e181b5d51bce13fdef6771bf2ae3b8fc77fea010c7b9fd3627351303fc576c3ef0d5e8fc0558d29f85f7eb7bf56daa4ddae9132d783b2a71e291ac75f9964e7ec4d0d2451cbbc72fdf0
16 63f4e6cee8205 5ab6de889d5522327652cdc4650219df9f850be8fca5b066d89fdc852daedffe0cbe2ee87a241b7f81f80916c80025615794c9d606e8e2489c33b868f79b957906a06ec50c90574b5f2f005eb242ef7e106d462928d5cfcc2a8b4409007f4586943c05b45a1f617b9c080e8b4887c87ca87c62d75f844c5166e3db08f8390857
17 63f4e6cee83b4 841d08a7036e8a35ee4210f3ef14a5e6038b0dcf43151163769c3fbd2ab2bb1c048d8bd5de2e5824b60bdc25d52addc43a9912fe9d9bef414fcdb6501a9866c68e055a57112b0f18fe7d14cdf450b2795ef95a32166d9aff352c6964b53c5c60494e59ff6d97e61f9058a753c8f3e177b0e60a8e4bfdf7032894268e0315382c
18 63f4e6cee8563 ae30b2b4a74118e7a57400a485338344b746a75fd3a2cec0ddbbb3ed459488872cc792880823d405df14014c3bc922171277a44abf36f6a13ca5131166dec879a162cc71908efba82a795d66b611967ae83509e39c368b09bd9b99b49f0a66d4a748f9b7c40b6081cdbc27216bddc83b5c79f8311b620cfab3c8d9958686f4cf
19 63f4e6cee8712 0e5a02a0d355a75a45c8ce395fc6a583a6f2a9ce33ea84abc097b5ec696fa083e39adb3453fb3d29e7f6f5db7825f6fdb85ff5c330e88e1a3f07009431f8ecd00504bbfbb1c483408b7adf7bf68b6d84112af9e42e42e88b796b0a458ba434a3801ac613be1faa27fbe86d52c328a0450623365b1b54ce1559776e4e31cc2617
randomness:7721, clocksused:20480
Seuraavassa satunnaisuutta käyttäen uusinta –pseudorandom satunnaisbittigeneraattoria:
$ ./newressu --pseudorandom
00000 08244457187065191402680035174774135288153032063260847296400488218
00001 94690959881770658540633627578224074647551721660812442615070042663
00002 63767866312899265438764984146765169760167687933985259472694929000
00003 48669584093668823976530011280425019595193079653033603276418513166
00004 49674138361191332823282555149600276637003883026350890567134377037
00005 12704475800646694934770999955672088881631681194392837080847178397
00006 94231230971149104627153047443428018860273861518472370409529368655
00007 44177713588974381992841613400897990454379505506914575309845021098
00008 19415866285254047665031471782503676759925438720070880749107387784
00009 66756439725415377997482645577451087265097622714981817382581876969
$
Kirjoitin samalla vauhdilla vielä uudestaan ressun ja pseudoressun. Uudet versiot ovat nimeltään ressu2 ja pseudoressu2. Nämä vaativat vielä lisätutkimusta. Vanhat versiot jäävät vielä nimillä ressu ja pseudoressu, ja newressu oletuksena ajaa vanhan ressun.
#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)) )
static 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) // ressu JariK 2013
{
int c, d, byte;
unsigned char e;
static int f = 0, prevbyte = -1;
static unsigned char g = 0;
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; // exclusive or data with byte
if(prevbyte != byte) {
prevbyte = byte;
randomness++;
}
}
for(d = 0; d < size; d++) { // swap
g = g << 1;
g ^= buffer[d];
g ^= (clock() & 0xff); // processor time (for randomness)
f = (f + g + 2) % size;
e = buffer[d];
buffer[d] = buffer[f];
buffer[f] = e;
}
}
}
#define DEBUG16A 2
#define aDEBUG17 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)
{
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;
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 DEBUG17
ressu_dump("ressu2", sizeof(ressu), ressu, 32);
#endif
#ifdef DEBUG16A
if(stats) {
fprintf(stdout,"rounds:%d", d);
fprintf(stdout,", randomness:%d", randomness);
fprintf(stdout,", clocksused:%d", clocksused);
fprintf(stdout,"\n");
}
#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 DEBUG17
ressu_dump("data 1", 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 DEBUG17
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
{
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 DEBUG17
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 DEBUG17
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(pseudoressu_key); // replace key with new random one
#ifdef DEBUG17
ressu_dump("new key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
#ifdef DEBUG17
ressu_dump("data 2", size, buffer, 32);
#endif
}
void ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023
{
ressu2_bytes(size, buffer);
pseudoressu2_bytes(size, buffer);
//urandom_bytes(size, buffer);
}
DEBUG17 testilista ressu2 ajosta: Ressu2 alkuiset rivit listaavat ressu2:n generoiman blokin ja datarivit listaavat tuloksen rivi kerrallaan. Ohjelman tulostamat rivit alkavat numerolla.
$ ./newressu --ressu2 -x
ressu2 32 00 4b 51 01 e5 3c 74 e2 97 d2 72 24 34 37 18 b7 5e 58 f8 33 4d d6 99 c5 61 3a c8 4b d7 1e 92
ressu2 d2 47 0b 06 75 a0 ea fa ba c0 df ef 35 78 e2 59 58 5b ce 30 78 60 52 d9 b1 61 20 9a b0 23 10 9e
ressu2 8e dd df c1 52 20 bf fc a9 e8 b3 06 ed 94 0a e1 80 62 69 1d d5 a3 8d 7b 4e 6f eb fc 6c 0a 96 3d
ressu2 1a 21 86 e3 d1 2b c2 ff 16 53 fe 7e 83 da 8a a7 a7 32 9c 63 0a ba d5 6f d2 85 cf e5 5f 2e a8 3a
ressu2 c0 78 f0 93 b8 48 b5 0d 83 66 c7 b2 1b 57 a3 a4 39 be e6 1f 18 42 eb 23 a4 b7 af af 44 1e 53 f5
ressu2 66 2c 63 87 4e 6c aa 53 b7 26 9b c6 5b cd 53 78 24 30 03 13 0f e3 e9 a5 8e bc db bf 10 d9 57 40
ressu2 9b 06 0c 6f 1e b0 05 a0 6c 19 c3 a2 d9 75 57 b7 95 ad 1c e7 9f a0 62 c1 f5 00 1c 5c 76 68 20 61
ressu2 4a cc 9a 27 67 7d 85 b9 11 c4 4c ec 88 18 58 fd 30 b7 e2 42 e3 cc b8 b7 0d 76 60 2f 7e 89 1a 19
ressu2 4b f6 01 8d af 73 15 14 79 58 4d 01 b9 e6 81 a6 32 59 d9 05 1c d1 03 0e 05 be 79 4e 18 3a 59 26
ressu2 44 db 41 80 04 fa 4e 0d df 9a 8b 00 0f f8 60 73 94 16 06 13 8d 9f 6c 96 d6 e8 72 bb e0 91 9f 03
ressu2 02 41 32 53 a9 2d 6d 74 51 4a 62 f2 34 04 16 f2 0d 3a c0 b4 15 cf 78 c8 85 0d f1 2d 4e ba 16 b4
ressu2 3f b4 9e d4 0a d0 fb a2 de 13 b7 cb 31 fb 12 47 c3 3d fb 58 c2 ca 63 9b 55 8e 90 ac ff 66 54 89
ressu2 d1 b0 4d d7 97 03 c2 57 d1 09 2c 58 31 75 5a 36 86 ff 0e 41 ea d0 b8 d2 9c 3b 2f dd 0b a7 20 a5
ressu2 14 77 f5 26 9b be c7 c3 a5 4b a1 83 96 6d 24 49 0d e2 02 db 8e cf 83 f0 ed e8 46 3b 22 1b ee a7
ressu2 a4 43 ac 4b 51 06 bb f8 9a aa 25 5a ce 76 cd fc c8 76 79 9e 3f aa c3 f0 b4 6a c2 24 7f 36 77 c8
ressu2 c6 69 14 68 6a 0d c4 0c 33 0b 67 99 69 82 a2 60 f3 d2 9b f4 8a eb 2b 46 d6 02 a0 68 9c 8e e6 12
ressu2 ab c2 04 15 c5 7a f0 da 80 4d 01 52 98 e6 5f 85 30 89 ac df 7d a6 77 6a 65 90 a6 06 fa 0b c3 d7
ressu2 f8 e7 09 d3 3b 6e 92 f0 34 f2 58 ff 75 84 eb 4f 73 44 be 8c 3e 72 e7 4b 1d e2 b7 81 14 23 1f f2
ressu2 d2 ab bd 67 c2 d9 f2 14 73 14 ca a8 b0 32 90 f2 9a fb 4b f5 bf 2f 55 06 8c 09 31 13 e9 c2 e0 f2
ressu2 ea 50 d2 25 36 df 6b 6c ce ea df da 29 59 5c d1 b9 d5 75 08 25 35 fe 96 24 16 58 83 ea 41 1d 84
ressu2 3f 42 9a 19 48 19 dc 36 79 fb 21 80 ab d1 01 8e c9 e1 73 3e 41 c2 b6 4f 1c 4d 4b 35 a3 a2 20 82
ressu2 72 92 30 aa cc 3e e8 97 64 44 03 80 b9 da f1 aa 81 44 68 4b 51 0b 38 b5 1b 18 e4 13 1a f0 0e 42
ressu2 fa 2a 6f bf f0 e5 ce 08 cc 5e 30 be be d3 00 8e 5c 04 50 d4 89 a6 f9 96 f3 71 8c 1d 14 6e cc d6
ressu2 41 a9 2b 10 18 05 76 65 01 34 df 48 ec b7 cb ae 81 32 4a 2e df 55 54 18 95 32 ce ab e1 3c 2c f6
ressu2 96 6b 6a 4b 0f a4 7a 28 e6 92 bc 3b 78 bd e0 19 88 e4 10 94 15 ac 99 a3 b9 6d e2 c4 03 c4 e7 a8
ressu2 a4 bf d4 94 80 25 16 fc 4a 6c 49 4d bc b9 84 51 c1 c7 cd a6 df 41 db 06 0e 8c 09 c1 5e 08 9c 60
ressu2 70 e9 e6 e8 ff e8 66 20 ee 30 07 a4 6e 8b fc e4 fe 30 dd d3 a1 d4 bd c0 ab 30 41 76 7b 99 cc a5
ressu2 28 b4 ed 3f bf e9 5e 7a 69 ec b2 e2 34 25 6b cd 43 8e 6d 2e 61 00 88 5d 05 18 5b 1a dd 50 f6 2f
ressu2 93 a8 9d df 6b c9 91 8a ce ff 30 9c 73 83 02 d7 25 10 ff 13 6e 4b 9c ba e3 67 5b 96 ce 45 a9 47
ressu2 d8 a5 cb 25 53 b6 0f c7 ba 04 8c 43 c3 f4 3e 83 39 24 1d 74 33 cd 02 c4 b3 07 bb 93 2e 5d f8 20
ressu2 26 af 13 bd 87 47 3e 0a db 63 c3 b2 38 16 77 04 42 ac c2 fc f6 a1 d5 2d 6c 95 f0 bf 75 06 39 da
ressu2 be 3a 3c 86 76 35 2e 8d e8 af cb 67 14 f3 9a fd 04 24 6b a9 7b c9 3f dd 65 b9 f7 19 6a 03 37 bf
ressu2 70 00 5c 62 05 fa ce 96 46 8b 6a 63 3e a2 3c f0 10 5c 30 ec d3 bf 46 6c 27 5d 1b bc 73 6b 3e 42
ressu2 bc d8 1e 4f 3a ec 99 71 7b 4d b6 b9 cd 50 73 3f 33 1c 31 f9 58 eb bb 4e 1e 0a 21 68 cf ef fd bf
ressu2 c5 07 ee 94 48 5b e3 76 63 b9 96 93 e5 6e 77 2c 4c f7 b2 31 f4 a1 06 40 4a 6d 0c 7c 5f 70 c8 9b
ressu2 eb 00 7e 19 48 97 76 15 6f 46 62 23 c5 dc 4c b0 f9 5c e1 13 b9 7f a8 60 8e c0 fe 4d ed c2 93 a1
ressu2 03 24 fd 78 d5 0b 0e 5b 96 9c ce fb b6 76 38 06 7b ed 61 a0 9c e3 80 1f e7 2c 2d b8 50 b7 8d 5c
ressu2 11 28 33 21 34 72 cc 1d bb 64 7d f1 2d 25 02 25 5a 6a c4 cb 1e ea 8c 2e 27 9d 43 47 12 79 c4 9a
ressu2 ac d0 16 78 3e ab e4 23 64 c4 e8 1f 70 21 ef ed 2c a0 41 19 c7 09 24 f5 72 e3 25 30 64 bd b2 a1
ressu2 cd a7 06 56 1a 37 a2 69 84 56 08 f8 60 6b 22 ac 52 2d 16 58 f2 fa 02 10 97 50 4b 4f 11 71 1a ea
ressu2 21 4b ba 37 30 06 62 28 78 de 28 86 4d 23 35 75 29 fc 11 43 33 f3 1e 4c 9a bd b3 9a 84 d4 df 29
ressu2 74 e8 ab 5b ae 13 01 d6 91 3e b8 5a e6 7c 60 28 e6 27 27 c6 02 34 0d 00 64 b5 a5 ec e0 a4 c7 8c
ressu2 95 2b 68 dc ec c9 eb dd e7 d0 2d 3c 0d 1d c4 7f 39 1c 08 00 22 55 3a fa f0 b6 e5 c2 52 8a b0 d3
ressu2 70 3e f6 63 cb 29 90 8e 92 e9 0b 24 14 15 5d 1f 45 a8 4e 33 0f d8 7a 4c 09 23 29 d6 94 ef 71 fd
ressu2 98 c2 ef c0 a9 b4 4c 5f 2c 2a 8a f0 e1 d2 74 e5 64 6e 66 90 4d 4b 3d bf 4f 69 84 25 d9 ed 72 02
ressu2 29 2d 5d 91 d0 15 48 8e 9c 34 c5 3b 3d 38 e4 d5 bc 69 ea 61 79 cd 41 7b e3 57 e4 45 ed 5c 89 9a
ressu2 9d cc 21 90 f8 0f e1 18 74 47 75 58 b4 5a 0a 52 eb ef f2 63 77 ea a7 c4 e2 0f 0b 6b f2 94 2e bd
ressu2 ac 83 70 b6 4c 95 f0 c8 29 3e 25 07 db fb e8 06 0d 9e 7a 74 6c 61 91 72 56 fd ae 02 7a 43 5e 93
ressu2 19 37 60 71 b9 40 26 7b b3 91 84 fc 09 c6 fb 1c 87 7e 5f 2f 42 31 22 c7 93 a9 95 fe 30 fa 61 cc
ressu2 a2 2d ab 57 11 71 99 44 f9 9d 17 9e 75 0f c2 3b 3e cf 80 46 e8 a6 6a b1 4f f6 0e 6c ba 9f 0a 3a
ressu2 c9 f8 1a 2d 25 e6 75 c4 9c 64 b5 da 26 3a 00 67 14 d6 8f 85 94 b4 41 43 43 e6 5d ea b0 a9 3c 05
ressu2 ae 6d 48 fd e2 fe 9c 94 dd 01 d3 9a c0 96 a4 16 bb 2e f9 63 33 93 5b fa aa 72 36 81 a6 26 50 ec
ressu2 ed e2 9a 8d 3c 76 c5 cf 98 26 cd 7d 18 e6 70 c6 95 09 09 1d 8a f3 6f 8b 5d 82 49 38 be b7 68 fd
ressu2 34 da 43 90 d6 69 ba a3 d6 2a 0d 85 09 49 88 0b f5 ba ea 35 a9 72 e4 5a ea aa 2a ed ed 3c 80 d1
ressu2 6e 00 71 78 83 32 62 92 6c 1e 69 37 f0 00 a2 30 cc 4b 7e 3e 3f 38 8a 64 a8 8f 8d c0 1e 25 30 1d
ressu2 2e 1c dd 72 0c c1 e9 f2 07 9a e4 36 06 50 83 f1 4d 97 4d 93 4c bb a8 ef a2 87 ed 1a 0e a6 ee d5
ressu2 ef 2a f2 5e ab 62 a7 71 c3 e0 23 6c 18 59 95 c0 bb 0b 65 bb 26 c6 db 22 d6 1d 43 b1 b9 cd 4e b6
ressu2 c6 fa 00 7a c8 72 a6 cc f5 27 b0 a6 9d 0f 22 4c 5c 06 25 75 1a c3 46 86 98 3c aa 2d d0 a4 95 2d
ressu2 56 e5 00 d2 af 8d 99 44 7e fd c7 59 12 01 05 8b bc e9 24 8a f0 c5 9b 25 bc ae f2 0f f8 9c 03 e3
ressu2 43 06 8e 9e a6 3d 9d 2e 2d 81 79 43 23 6a 56 58 34 8d 9c 35 75 cd 17 e2 a1 1d e0 5a 15 16 d6 48
ressu2 ec 46 0d 16 72 cf 1e 4d 14 6d b6 95 b8 1f c9 ae d8 19 50 4b 03 32 2e 8f 74 2f 64 e8 bd a3 3d 13
ressu2 91 2d 77 b2 00 4f 0f 8d db cb fa 04 bf 98 34 e3 3e 20 38 eb 38 33 0a 5e ec d4 e0 67 b9 c8 7d 1d
ressu2 bc 93 5e 4a 72 12 be 1d 6f 89 67 e1 9e 72 24 ce 11 41 90 3e e0 8e de 6e 77 84 d9 6e 0e ea eb c6
ressu2 e9 b4 8b 62 a7 f6 bc 8e 54 07 26 f5 ff 51 07 b5 b2 9d 71 28 91 03 20 e0 95 08 d0 7c 23 00 ce 0f
data 32 00 4b 51 01 e5 3c 74 e2 97 d2 72 24 34 37 18 b7 5e 58 f8 33 4d d6 99 c5 61 3a c8 4b d7 1e 92
data d2 47 0b 06 75 a0 ea fa ba c0 df ef 35 78 e2 59 58 5b ce 30 78 60 52 d9 b1 61 20 9a b0 23 10 9e
data 8e dd df c1 52 20 bf fc a9 e8 b3 06 ed 94 0a e1 80 62 69 1d d5 a3 8d 7b 4e 6f eb fc 6c 0a 96 3d
data 1a 21 86 e3 d1 2b c2 ff 16 53 fe 7e 83 da 8a a7 a7 32 9c 63 0a ba d5 6f d2 85 cf e5 5f 2e a8 3a
data c0 78 f0 93 b8 48 b5 0d 83 66 c7 b2 1b 57 a3 a4 39 be e6 1f 18 42 eb 23 a4 b7 af af 44 1e 53 f5
data 66 2c 63 87 4e 6c aa 53 b7 26 9b c6 5b cd 53 78 24 30 03 13 0f e3 e9 a5 8e bc db bf 10 d9 57 40
data 9b 06 0c 6f 1e b0 05 a0 6c 19 c3 a2 d9 75 57 b7 95 ad 1c e7 9f a0 62 c1 f5 00 1c 5c 76 68 20 61
data 4a cc 9a 27 67 7d 85 b9 11 c4 4c ec 88 18 58 fd 30 b7 e2 42 e3 cc b8 b7 0d 76 60 2f 7e 89 1a 19
data 4b f6 01 8d af 73 15 14 79 58 4d 01 b9 e6 81 a6 32 59 d9 05 1c d1 03 0e 05 be 79 4e 18 3a 59 26
data 44 db 41 80 04 fa 4e 0d df 9a 8b 00 0f f8 60 73 94 16 06 13 8d 9f 6c 96 d6 e8 72 bb e0 91 9f 03
data 02 41 32 53 a9 2d 6d 74 51 4a 62 f2 34 04 16 f2 0d 3a c0 b4 15 cf 78 c8 85 0d f1 2d 4e ba 16 b4
data 3f b4 9e d4 0a d0 fb a2 de 13 b7 cb 31 fb 12 47 c3 3d fb 58 c2 ca 63 9b 55 8e 90 ac ff 66 54 89
data d1 b0 4d d7 97 03 c2 57 d1 09 2c 58 31 75 5a 36 86 ff 0e 41 ea d0 b8 d2 9c 3b 2f dd 0b a7 20 a5
data 14 77 f5 26 9b be c7 c3 a5 4b a1 83 96 6d 24 49 0d e2 02 db 8e cf 83 f0 ed e8 46 3b 22 1b ee a7
data a4 43 ac 4b 51 06 bb f8 9a aa 25 5a ce 76 cd fc c8 76 79 9e 3f aa c3 f0 b4 6a c2 24 7f 36 77 c8
data c6 69 14 68 6a 0d c4 0c 33 0b 67 99 69 82 a2 60 f3 d2 9b f4 8a eb 2b 46 d6 02 a0 68 9c 8e e6 12
data ab c2 04 15 c5 7a f0 da 80 4d 01 52 98 e6 5f 85 30 89 ac df 7d a6 77 6a 65 90 a6 06 fa 0b c3 d7
data f8 e7 09 d3 3b 6e 92 f0 34 f2 58 ff 75 84 eb 4f 73 44 be 8c 3e 72 e7 4b 1d e2 b7 81 14 23 1f f2
data d2 ab bd 67 c2 d9 f2 14 73 14 ca a8 b0 32 90 f2 9a fb 4b f5 bf 2f 55 06 8c 09 31 13 e9 c2 e0 f2
data ea 50 d2 25 36 df 6b 6c ce ea df da 29 59 5c d1 b9 d5 75 08 25 35 fe 96 24 16 58 83 ea 41 1d 84
data 3f 42 9a 19 48 19 dc 36 79 fb 21 80 ab d1 01 8e c9 e1 73 3e 41 c2 b6 4f 1c 4d 4b 35 a3 a2 20 82
data 72 92 30 aa cc 3e e8 97 64 44 03 80 b9 da f1 aa 81 44 68 4b 51 0b 38 b5 1b 18 e4 13 1a f0 0e 42
data fa 2a 6f bf f0 e5 ce 08 cc 5e 30 be be d3 00 8e 5c 04 50 d4 89 a6 f9 96 f3 71 8c 1d 14 6e cc d6
data 41 a9 2b 10 18 05 76 65 01 34 df 48 ec b7 cb ae 81 32 4a 2e df 55 54 18 95 32 ce ab e1 3c 2c f6
data 96 6b 6a 4b 0f a4 7a 28 e6 92 bc 3b 78 bd e0 19 88 e4 10 94 15 ac 99 a3 b9 6d e2 c4 03 c4 e7 a8
data a4 bf d4 94 80 25 16 fc 4a 6c 49 4d bc b9 84 51 c1 c7 cd a6 df 41 db 06 0e 8c 09 c1 5e 08 9c 60
data 70 e9 e6 e8 ff e8 66 20 ee 30 07 a4 6e 8b fc e4 fe 30 dd d3 a1 d4 bd c0 ab 30 41 76 7b 99 cc a5
data 28 b4 ed 3f bf e9 5e 7a 69 ec b2 e2 34 25 6b cd 43 8e 6d 2e 61 00 88 5d 05 18 5b 1a dd 50 f6 2f
data 93 a8 9d df 6b c9 91 8a ce ff 30 9c 73 83 02 d7 25 10 ff 13 6e 4b 9c ba e3 67 5b 96 ce 45 a9 47
data d8 a5 cb 25 53 b6 0f c7 ba 04 8c 43 c3 f4 3e 83 39 24 1d 74 33 cd 02 c4 b3 07 bb 93 2e 5d f8 20
data 26 af 13 bd 87 47 3e 0a db 63 c3 b2 38 16 77 04 42 ac c2 fc f6 a1 d5 2d 6c 95 f0 bf 75 06 39 da
data be 3a 3c 86 76 35 2e 8d e8 af cb 67 14 f3 9a fd 04 24 6b a9 7b c9 3f dd 65 b9 f7 19 6a 03 37 bf
data 70 00 5c 62 05 fa ce 96 46 8b 6a 63 3e a2 3c f0 10 5c 30 ec d3 bf 46 6c 27 5d 1b bc 73 6b 3e 42
data bc d8 1e 4f 3a ec 99 71 7b 4d b6 b9 cd 50 73 3f 33 1c 31 f9 58 eb bb 4e 1e 0a 21 68 cf ef fd bf
data c5 07 ee 94 48 5b e3 76 63 b9 96 93 e5 6e 77 2c 4c f7 b2 31 f4 a1 06 40 4a 6d 0c 7c 5f 70 c8 9b
data eb 00 7e 19 48 97 76 15 6f 46 62 23 c5 dc 4c b0 f9 5c e1 13 b9 7f a8 60 8e c0 fe 4d ed c2 93 a1
data 03 24 fd 78 d5 0b 0e 5b 96 9c ce fb b6 76 38 06 7b ed 61 a0 9c e3 80 1f e7 2c 2d b8 50 b7 8d 5c
data 11 28 33 21 34 72 cc 1d bb 64 7d f1 2d 25 02 25 5a 6a c4 cb 1e ea 8c 2e 27 9d 43 47 12 79 c4 9a
data ac d0 16 78 3e ab e4 23 64 c4 e8 1f 70 21 ef ed 2c a0 41 19 c7 09 24 f5 72 e3 25 30 64 bd b2 a1
data cd a7 06 56 1a 37 a2 69 84 56 08 f8 60 6b 22 ac 52 2d 16 58 f2 fa 02 10 97 50 4b 4f 11 71 1a ea
data 21 4b ba 37 30 06 62 28 78 de 28 86 4d 23 35 75 29 fc 11 43 33 f3 1e 4c 9a bd b3 9a 84 d4 df 29
data 74 e8 ab 5b ae 13 01 d6 91 3e b8 5a e6 7c 60 28 e6 27 27 c6 02 34 0d 00 64 b5 a5 ec e0 a4 c7 8c
data 95 2b 68 dc ec c9 eb dd e7 d0 2d 3c 0d 1d c4 7f 39 1c 08 00 22 55 3a fa f0 b6 e5 c2 52 8a b0 d3
data 70 3e f6 63 cb 29 90 8e 92 e9 0b 24 14 15 5d 1f 45 a8 4e 33 0f d8 7a 4c 09 23 29 d6 94 ef 71 fd
data 98 c2 ef c0 a9 b4 4c 5f 2c 2a 8a f0 e1 d2 74 e5 64 6e 66 90 4d 4b 3d bf 4f 69 84 25 d9 ed 72 02
data 29 2d 5d 91 d0 15 48 8e 9c 34 c5 3b 3d 38 e4 d5 bc 69 ea 61 79 cd 41 7b e3 57 e4 45 ed 5c 89 9a
data 9d cc 21 90 f8 0f e1 18 74 47 75 58 b4 5a 0a 52 eb ef f2 63 77 ea a7 c4 e2 0f 0b 6b f2 94 2e bd
data ac 83 70 b6 4c 95 f0 c8 29 3e 25 07 db fb e8 06 0d 9e 7a 74 6c 61 91 72 56 fd ae 02 7a 43 5e 93
data 19 37 60 71 b9 40 26 7b b3 91 84 fc 09 c6 fb 1c 87 7e 5f 2f 42 31 22 c7 93 a9 95 fe 30 fa 61 cc
data a2 2d ab 57 11 71 99 44 f9 9d 17 9e 75 0f c2 3b 3e cf 80 46 e8 a6 6a b1 4f f6 0e 6c ba 9f 0a 3a
data c9 f8 1a 2d 25 e6 75 c4 9c 64 b5 da 26 3a 00 67 14 d6 8f 85 94 b4 41 43 43 e6 5d ea b0 a9 3c 05
data ae 6d 48 fd e2 fe 9c 94 dd 01 d3 9a c0 96 a4 16 bb 2e f9 63 33 93 5b fa aa 72 36 81 a6 26 50 ec
data ed e2 9a 8d 3c 76 c5 cf 98 26 cd 7d 18 e6 70 c6 95 09 09 1d 8a f3 6f 8b 5d 82 49 38 be b7 68 fd
data 34 da 43 90 d6 69 ba a3 d6 2a 0d 85 09 49 88 0b f5 ba ea 35 a9 72 e4 5a ea aa 2a ed ed 3c 80 d1
data 6e 00 71 78 83 32 62 92 6c 1e 69 37 f0 00 a2 30 cc 4b 7e 3e 3f 38 8a 64 a8 8f 8d c0 1e 25 30 1d
data 2e 1c dd 72 0c c1 e9 f2 07 9a e4 36 06 50 83 f1 4d 97 4d 93 4c bb a8 ef a2 87 ed 1a 0e a6 ee d5
data ef 2a f2 5e ab 62 a7 71 c3 e0 23 6c 18 59 95 c0 bb 0b 65 bb 26 c6 db 22 d6 1d 43 b1 b9 cd 4e b6
data c6 fa 00 7a c8 72 a6 cc f5 27 b0 a6 9d 0f 22 4c 5c 06 25 75 1a c3 46 86 98 3c aa 2d d0 a4 95 2d
data 56 e5 00 d2 af 8d 99 44 7e fd c7 59 12 01 05 8b bc e9 24 8a f0 c5 9b 25 bc ae f2 0f f8 9c 03 e3
data 43 06 8e 9e a6 3d 9d 2e 2d 81 79 43 23 6a 56 58 34 8d 9c 35 75 cd 17 e2 a1 1d e0 5a 15 16 d6 48
data ec 46 0d 16 72 cf 1e 4d 14 6d b6 95 b8 1f c9 ae d8 19 50 4b 03 32 2e 8f 74 2f 64 e8 bd a3 3d 13
data 91 2d 77 b2 00 4f 0f 8d db cb fa 04 bf 98 34 e3 3e 20 38 eb 38 33 0a 5e ec d4 e0 67 b9 c8 7d 1d
data bc 93 5e 4a 72 12 be 1d 6f 89 67 e1 9e 72 24 ce 11 41 90 3e e0 8e de 6e 77 84 d9 6e 0e ea eb c6
data e9 b4 8b 62 a7 f6 bc 8e 54 07 26 f5 ff 51 07 b5 b2 9d 71 28 91 03 20 e0 95 08 d0 7c 23 00 ce 0f
00000 32004b5101e53c74e297d27224343718b75e58f8334dd699c5613ac84bd71e92
00001 d2470b0675a0eafabac0dfef3578e259585bce30786052d9b161209ab023109e
00002 8edddfc15220bffca9e8b306ed940ae18062691dd5a38d7b4e6febfc6c0a963d
00003 1a2186e3d12bc2ff1653fe7e83da8aa7a7329c630abad56fd285cfe55f2ea83a
00004 c078f093b848b50d8366c7b21b57a3a439bee61f1842eb23a4b7afaf441e53f5
00005 662c63874e6caa53b7269bc65bcd5378243003130fe3e9a58ebcdbbf10d95740
00006 9b060c6f1eb005a06c19c3a2d97557b795ad1ce79fa062c1f5001c5c76682061
00007 4acc9a27677d85b911c44cec881858fd30b7e242e3ccb8b70d76602f7e891a19
00008 4bf6018daf73151479584d01b9e681a63259d9051cd1030e05be794e183a5926
00009 44db418004fa4e0ddf9a8b000ff86073941606138d9f6c96d6e872bbe0919f03
$$
Testataan vielä pseudoressu2:sta DEBUG17 debukilla: ressu2 rivit ovat ressu2:n generoimia rivejä, data 1 rivit ovat ressu2_bytes():in palauttamia rivejä. First key on ensimmäinen pseudoressu2:n avain. Topup-rivi lisää satunnaisuutta avaimeen. Next data rivit ovat pseudoressun palauttamaa dataa. Data 2 rivit ovat pseudoressu2:n palauttamia rivejä. New key on pseudoressu_bytes():in jälkeen vaihdettu uusi avain.
./newressu --pseudoressu2 -x
ressu2 8a ba bf 65 b0 40 6b ad be d7 36 9b bf d7 fe a5 14 57 07 0c c1 12 5d d9 23 c8 a1 4d 47 40 8e 50
ressu2 e7 d6 73 96 df fb ca 0f ab 50 d2 0c a7 0c 49 c0 ad d2 4f ac 53 66 9e d9 95 b8 4b 48 41 0f 22 b5
ressu2 f9 73 7c c0 bd 04 6f c1 6e cf 1a b6 0f 00 b8 ee 87 bf 21 d2 39 64 e1 38 b6 3b c0 34 9c 35 9b b0
ressu2 88 35 fb ee ce c8 9a b6 7a 11 71 c8 cf 6e 6e 1a db 94 48 06 20 2a 3f 90 9c 6f 73 4a 1c 87 48 a3
ressu2 c1 28 94 d3 17 73 7c 11 1c 76 6e c4 40 e4 32 b8 05 14 3a 1b 8f 52 da 23 da 17 f2 b3 bc ff 49 bb
ressu2 dd 61 c5 74 a3 4e c2 d9 da fe fa e6 63 0d 0b fc 1a cc 3a 53 48 cc f0 a5 60 52 97 75 4a 63 00 2b
ressu2 c6 46 1f 5d d8 2a d6 b2 cb 87 c1 2a 22 8c 44 4c 92 50 ee 9d 1c b1 24 d9 f7 86 97 fc cb b2 db 0c
ressu2 47 19 fd 46 95 dc 65 16 b8 5b 19 00 60 59 c3 cc 5e f9 8a ae fc f6 60 67 e2 65 0e 24 78 68 5c ba
ressu2 2b 74 11 a6 07 de 7e 5b 03 0f b8 20 45 d7 2c 29 fc e1 d9 bd 57 72 88 a7 5e 59 69 91 e4 f7 95 e7
ressu2 8e 51 d9 8b e3 f1 18 9b e0 cc bb b1 82 b1 68 08 39 ab 9e 8f 1b 57 c1 2b 1e fd 2b 65 b9 62 61 80
ressu2 3a fd 2a ce 94 04 71 83 8d 08 9f 7f 99 33 a5 ae ba 29 96 ae 7e 9b 43 68 ae 56 56 2c f8 9c 90 77
ressu2 f5 26 a9 56 66 4c 2a ca d6 64 f5 da 1c c7 91 01 51 f7 27 63 50 8d bc a9 f8 2d 16 7a be 58 e8 af
ressu2 93 79 5d 85 26 9b 1e fa 9f 82 4e d2 ae e2 cd 7d 83 83 48 f0 59 4a 17 37 c7 b6 b8 0a b8 94 a6 20
ressu2 7f aa 2a 9a 0f a4 18 c2 17 cc c5 22 37 0b 13 65 20 09 ff 80 6d f1 0b 78 26 1f 61 38 fb 36 ea 44
ressu2 5a 40 69 60 46 1f d7 0b 10 c2 ae fc ed b0 02 b0 48 ca 9b 9a 35 54 0b 8c c9 b9 d2 59 46 45 dd 41
ressu2 80 48 f8 2b 2a a5 a0 d4 ab a8 64 0a ce 85 ff fa 73 03 e0 ee 6b 8e 61 b8 09 7f 2b ad 78 06 d3 86
ressu2 8d 29 5b bd 3e c4 60 5b 35 ce 3b f9 a9 32 ff a7 33 70 31 d9 8c 32 ce b0 d2 dd 8d 24 e5 93 d4 29
ressu2 f4 c3 6a 83 2e 33 1b 3e 82 30 20 7d 82 db aa 6f 20 2a 2d 46 26 30 0b ad 87 cb 60 4d 78 22 9b dd
ressu2 7e f1 69 93 76 d4 15 52 9d 50 6d 20 45 6d 8c cf 78 eb 51 db 1f 60 95 be 23 a2 e1 a0 d3 b0 b4 b2
ressu2 46 2e ac 5e c8 51 77 16 fd 82 66 01 0c 3b 66 55 8c 2d 66 de 47 39 1f d4 4a 03 58 64 45 b3 5a 81
ressu2 53 19 2d 31 f3 98 6c 8d 9f 62 d1 74 66 d1 65 00 69 9f 23 7b 53 e9 18 48 b6 56 f9 2e 88 a5 cd 39
ressu2 e9 0f f2 b9 5c 83 32 bd c7 96 a7 7d bf 90 72 86 ad 8a 7d 7e b7 54 6d 19 b3 4b 1b a7 35 43 d7 f4
ressu2 72 2c 86 d9 20 9d b5 27 49 df 57 0f 18 27 63 e5 18 f0 3b c5 ad 12 8a fb 79 f1 38 c7 0e 78 95 4c
ressu2 ce 8a 10 bc 72 ac ac 43 f7 56 8c 6d f7 ee fc 15 4a 1f 3a ca e1 5b 52 6a f5 dd f7 1c 96 18 73 a4
ressu2 af 2b 20 0a ae 10 b2 fd 52 08 ec 00 ef 5d e0 0c 8b 86 c9 80 84 a3 9b 57 61 83 ca f7 75 e1 41 3d
ressu2 ec 7d 47 40 4f 0a 2c 6f b0 46 77 99 03 44 77 3f df 56 2e 5f d7 b2 e5 56 cd 2f 2e d8 5f f1 d7 d6
ressu2 6a bc 40 b0 a0 3b 7c dd 7d 5b b9 19 70 d6 65 a7 7f 26 c1 ee ab 17 46 e5 c0 45 4d e9 f1 02 b9 a6
ressu2 8e 38 e9 7e 37 38 53 9b 62 20 af 86 17 cb 65 20 a5 af 52 85 ca d1 ab ff 80 db 86 d0 32 f5 bc 21
ressu2 5c 15 5c ed 9c d6 09 03 f1 78 76 2c 4b e0 f9 78 87 a1 96 80 eb 71 e9 9e 13 00 92 2f e0 0a 82 b6
ressu2 bc f6 ab 9e ff db a3 f8 ee 74 e4 b2 f0 34 61 86 72 e0 9d 68 f2 00 44 dc 1d 83 b5 17 3e e2 ff 4c
ressu2 73 50 0a 4e b7 41 89 d6 9b 37 31 10 9c 14 ef d4 a4 2b e5 dc 59 05 07 3f f8 5a 25 0d 7a fe 0f 85
ressu2 88 93 ec e0 2f 25 25 d0 9f c8 13 25 f6 ca d6 f1 e8 2d 33 5f 3a 73 17 22 a4 e6 7b 0c 7e 54 e7 e6
ressu2 95 f0 a1 48 4d 56 91 c4 e7 ae 0e c5 a4 3d 6d ff ff b3 17 fd 38 e9 4d 4b 85 bf d5 2a 31 3b 98 38
ressu2 83 ce d4 ac 7b a4 08 c4 bd a0 a2 4c 42 b4 7b 7d 40 2b 27 a9 75 00 82 82 09 78 77 92 3b 55 9a 00
ressu2 9f 64 ca b6 2e d7 10 14 bf b7 3c 05 68 ac cd c6 8b 02 2e a2 1e a9 44 ad ef 9e f9 1c 7f aa 9b 3c
ressu2 15 0b 45 79 88 70 e0 d6 e1 2b 93 50 bd 63 ca 4d a1 af 37 4a 96 4b 3b 7e ff 27 d5 a7 04 02 9d 94
ressu2 07 e7 b3 c8 31 3b ba e9 37 3c a0 f4 bf 29 ff 43 eb 88 da 11 c0 31 4a 64 71 31 93 6c a8 38 c7 5f
ressu2 a0 5f 0f 66 41 66 46 53 ab a2 37 f6 bd 1f 32 49 e5 c7 c4 e9 58 bf 96 9a d9 0d 0c cf db 62 f7 d7
ressu2 84 3d 0a ac 3f 28 aa 7c 6b da 18 ed a2 c7 73 d1 d9 2b 87 56 9a 15 ae 5e eb 95 96 fd be 9d 67 5a
ressu2 9a 2e 06 51 d6 7c cc 38 17 8d 07 f9 28 59 5d 66 35 e2 39 01 f2 7b f3 e0 6b 12 55 de 30 48 48 04
ressu2 e1 53 bc 19 6f 8d e2 15 f4 55 f8 1b 8e 10 e4 cf c1 d4 f9 e0 21 b7 16 e3 a5 73 b5 77 1a 27 e9 35
ressu2 d6 91 2f 47 8e d4 fc 7e 12 79 8c dd 5a d5 6b 15 6e 06 59 cc d0 cd d4 9b 17 1d 73 e2 c3 31 9b 11
ressu2 9b e0 b4 1e 6c a1 ec df b8 af 7a 64 5b 51 66 f4 30 f5 c6 81 2d be 75 7d 76 ee b4 0d 75 b6 67 e3
ressu2 80 14 b0 02 a1 1e c6 72 2d 7b 12 d4 b3 e0 ed e0 57 50 be 16 3f f1 fe de aa 91 98 83 f3 ed ff 3b
ressu2 74 7f 07 40 4e 81 b7 e3 f6 b6 f8 bf e8 73 64 8f 64 27 cb 0d 60 7d 73 07 5c d7 46 ad 9b d3 81 9d
ressu2 a8 ec 21 b0 15 bc e8 0e e1 0c d5 4e fb 0b 17 42 a6 db 3a 19 0f 51 77 e8 49 6b 9a a6 3f c7 08 0a
ressu2 00 49 fe ff da 7d 79 01 9d e3 e1 d2 8d a3 e1 05 de be 07 aa 77 89 d4 77 1b 22 28 39 55 b3 23 fe
ressu2 d3 17 d2 b3 f9 15 23 a5 62 80 2a 2f 5e 51 9d 51 ae 6e c6 d4 9b 47 19 8f 01 d5 0a 17 f5 ad e1 5e
ressu2 a3 63 69 4c 38 62 bb a7 dd 77 fe 3b f4 93 8e 59 fe 33 ea 97 01 1b 96 6e aa 05 35 77 72 eb 89 87
ressu2 56 27 84 0e 99 35 b3 5d 1d 1d d8 ad 00 27 ed f0 90 ab 20 40 e1 d1 35 9a 0f 16 ec 8f 0a 11 e2 48
ressu2 60 87 9d fe 41 8c 11 3d 29 a2 0b 6c 4e 0f 31 e1 e1 3a b3 0e ba 7b ee 13 48 78 d7 7a d0 58 b3 e1
ressu2 41 fa 73 6e 5a 5c 48 40 26 8d 5a f1 f2 af 44 6a 9b 2f 22 e2 1a e9 f9 be 8a a3 63 91 1e a7 ca 30
ressu2 d4 2b c3 d1 ff 92 b9 0e c8 2f a5 78 67 74 59 2b d5 5f 38 ab 36 8a dc 96 f6 6a 3f c1 24 a2 59 13
ressu2 70 fd ee 04 5a 97 4a 5f 59 02 2a 4f a2 1a 88 dc 4c 54 7d f4 ad 03 8a 6f 2f ce bf ae 15 2a ed d3
ressu2 2f 93 6d 23 66 cd d8 dd 93 8d 42 49 23 81 13 1b 86 9a fd 64 c8 ca f1 1f 1d 7f 60 ac 25 3b 5b 2b
ressu2 c6 1f 61 fc f3 43 a3 95 be 4c b5 78 2e 35 1a 71 24 a2 9d c4 6e 7d 5e 4c 7e 4f d2 97 8d 8d 7d 00
ressu2 57 a4 66 2a f1 fb 26 00 cd f0 4d 94 7e 03 81 66 e8 99 91 91 2c 67 1e fb 44 27 7d 1a 0a 27 c4 95
ressu2 4c 21 43 dd d3 3f d7 e6 52 51 cb b6 18 5c eb db 33 3a 41 e6 69 c0 d5 5b 5c ef 8e e3 3e f0 f1 7c
ressu2 7d 25 63 48 f0 3d b6 0d 34 ac 81 fe 50 24 b0 5a 09 99 0f 56 d5 7a c8 7f a7 17 b1 96 3e 4a 1f cc
ressu2 0e e4 b4 d4 3b 61 9e 3d 4f b5 de 7a 9f ae a5 2e 39 5d 16 1d 5a f7 00 c9 f5 7a 5f 1c d8 dc 69 ad
ressu2 2d 3f f0 8d ed 66 1d 1c 4e 86 00 9d c3 e8 5f be dc d0 6e e9 69 55 f8 08 85 52 f9 b2 34 e5 f2 5e
ressu2 2a 01 29 5c 47 ed cb cb 74 85 de f6 fb 4c a9 e6 aa 58 81 00 ad 39 bc 33 7b 4f c6 6f f2 9e af a3
ressu2 9f 7a bd 9b 13 e8 e6 cb ec 50 c6 78 b6 ff d1 46 1b 7a a4 a1 c1 ae 69 f7 2d 50 a9 d7 ec 52 a3 dc
ressu2 f9 02 b2 a0 af dc 67 46 b2 0b 97 e7 a4 1c d3 64 c8 ba a1 11 9a 12 5f 0a 35 3a a7 11 90 1c f6 59
data 1 8a ba bf 65 b0 40 6b ad be d7 36 9b bf d7 fe a5 14 57 07 0c c1 12 5d d9 23 c8 a1 4d 47 40 8e 50
first key 8a ba bf 65 b0 40 6b ad be d7 36 9b bf d7 fe a5 14 57 07 0c c1 12 5d d9 23 c8 a1 4d 47 40 8e 50
data 1 e7 d6 73 96 df fb ca 0f ab 50 d2 0c a7 0c 49 c0 ad d2 4f ac 53 66 9e d9 95 b8 4b 48 41 0f 22 b5
topup e7 d6 73 96 df fb ca 0f ab 50 d2 0c a7 0c 49 c0 ad d2 4f ac 53 66 9e d9 95 b8 4b 48 41 0f 22 b5
next data 63 06 2d 1a af 9e a9 38 f2 e4 c4 b7 4e 01 ec 6d 81 ed 33 b2 31 e1 57 e3 ac f9 ee 2d 3c 5d aa 4d
next data 85 ca db b2 1f 49 ee fc 6a 54 6f 14 bb 86 7e e3 0e 6d cb 5c 52 fb 60 ae f7 94 84 5c 78 e1 6d 29
next data 0b 78 1e 01 30 47 f1 a8 44 56 4e e2 4b a5 80 86 6d e6 e1 ff 4c 03 1d b5 53 e8 17 36 16 a9 33 55
next data ea 2e 91 99 4f 47 c5 8b 25 b0 e2 17 ea f0 a1 c0 83 3f 14 2a 20 3f 15 0c fb 0f 0f 59 d2 7a 79 68
next data 1c af 7e a8 82 cd 47 24 8a d9 ed 01 a9 54 7e 96 f2 4f fb ba 58 ed bf 62 bc 38 82 9e ff cd 91 bd
next data e2 b3 82 81 5f 63 74 4a 27 bf d0 66 4e 78 17 54 5a 03 7f 93 85 8a 7c 89 30 ac 89 45 25 24 e0 a2
next data 8f da 1d e1 d1 28 42 a6 45 99 1f 37 9b 97 39 9c 33 4b e5 d2 b5 48 13 6a a3 87 e8 b0 19 2a 44 35
next data c1 17 3e 3c fc 99 fe 8e 4a d8 bf 41 57 b0 20 f9 3b d0 c1 b8 9f 2f 27 70 11 0a df e1 cc 1a ec 3f
next data 0c 4e 35 40 d2 14 76 cb 33 e9 0b 61 69 a0 82 39 4a 48 7e 59 b4 02 de 08 41 0b 20 37 e8 d2 2a b5
next data 46 b4 55 1e 3f 24 48 41 ec 35 33 9d e0 f3 24 ce 68 84 4d db 5a 03 4c 5c 75 ba cb d2 b9 ba b5 b1
next data a5 7f 7b 1d e7 f6 80 fa 93 9e e5 a0 ec 99 15 d4 29 76 84 89 3d c9 02 0a 3e a5 af 15 49 6e c0 5d
next data a8 40 81 81 e2 f4 5b a6 94 04 81 90 c9 2d 0d 5e 3c 51 31 2b 0d a6 37 1f 48 a5 ee b9 86 9c 3c 7b
next data 49 e3 c0 c4 77 d5 3e b6 0c a3 fe a7 0c e9 b3 26 17 13 e5 af e9 96 7c 00 ba 0f fc d0 fa f6 c2 be
next data f0 07 3d 89 72 45 ce ba af 62 f7 4a a9 4f 7f f5 2d cf 3d b3 bb e7 1e 46 8f 16 68 15 3f 89 96 69
next data 02 79 77 47 61 7c ae 90 17 6e de 46 d7 f2 b7 ae ab fa 2e e3 44 3d 25 79 46 8f 18 02 94 08 ce 84
next data 01 71 85 ef 0f 66 51 d7 0c 39 ab a1 ad 9e c3 dd d7 0f 15 3c 3f 9c e5 0a 5a 36 e7 01 a8 62 1a 6e
next data 5b af 6f a6 1b 77 12 63 85 dd 72 56 31 b5 43 7a 2b b0 b6 8d a0 7c 22 d2 9f 2c 1d 72 0a 71 4a 86
next data 7f b2 c7 03 a2 f9 d2 7b b0 a6 04 4f 1e 72 2b de 01 1c d6 11 6a 94 ba 59 0b a7 ec 6d 4d bb 7f b2
next data 2e c9 dc c0 6e b1 4d c2 53 23 03 8c 1d 59 c9 c8 34 02 d1 17 50 34 8e 96 f7 44 d9 7a bb 7b 59 ff
next data 6a 20 d5 7b 67 81 c6 af 08 b1 75 7f 2b f7 d6 1a 9e 3e 37 9b ef 62 6f 10 1a b2 56 05 13 ea 19 ff
next data 07 ed e0 eb 1a d4 1f 90 9a 2e 11 b1 73 ac cd 2d 6a 69 99 ed 33 e2 bf 1f bf 9d 0f dc e3 c8 26 25
next data dc 99 58 46 cc 22 8e 01 81 03 b5 4e 36 90 c9 1f e4 2b 7e 15 da 18 9f 5e ee 57 d3 34 ba 24 f7 57
next data c4 23 a0 87 03 ff b2 23 46 8f e3 1b 28 f3 c9 5d 01 3d 51 29 89 fe 32 dd ca 39 0f 64 68 cc 7c 34
next data d8 e1 b5 d0 8e 6b c8 31 88 ac 95 59 ac 81 9a 98 78 49 2d 7a c7 c7 68 78 94 98 21 33 ac 55 56 4f
next data 3c 2c 29 ac 3e 37 ec 52 7f 4a 97 e4 ec 96 4f d2 4f 9a c9 65 fd 12 95 6c ab 5a ed 6e af c9 ee 9f
next data 23 28 73 7d da 6c 8a 15 d1 ae 54 2e 51 7b 3a 27 fd c8 12 98 ad 54 65 4b 0e d3 f9 a1 d6 1b ab 99
next data 71 a1 27 ee 2d 09 f5 6e e3 02 d1 14 79 db 49 b9 a0 e7 74 31 b1 62 4f 4f ac 05 06 2f 3f 16 e6 67
next data 4b a2 78 b6 cc 0f e5 1e 78 0d bd b5 c9 aa cd 22 31 74 80 28 12 f2 90 d8 a4 d2 1d 5c 74 5a 18 13
next data b2 3f bd f4 8b 97 1b 7a 6b e5 fc 65 a7 a4 91 ab b3 a0 c6 8a a6 4b 8b 8b 6f 74 53 bb 0f 06 bb 42
next data bc b7 fb 5d 60 15 40 a1 a9 a2 1c 6d c2 76 23 09 84 07 ce c4 df 2a 59 19 32 2e 18 4c ab 29 0b aa
next data ed 2f dc 10 91 6a f9 c4 bc 1b d8 71 92 aa d5 af f9 dd 3d b5 be 82 4a e9 9b af 4c 14 94 53 bc a0
next data 1a 72 98 95 7f 09 e8 74 2f f2 b6 b8 5d ef 7a 35 12 e8 2f 2d 2a 23 96 07 ea 39 e8 5b 6d 79 4d f7
next data a9 6b c1 2e c0 5c 68 f8 6b 31 95 c7 91 78 f7 15 1d 00 8e fd 18 9a e0 d5 fe da f1 5b 05 80 c5 fc
next data aa 2c 35 1b 08 b3 b8 a6 a4 cc 28 5c fc 11 4c 90 91 55 fa 52 01 79 1e 0f 05 c5 6e 4a 5c 1b 3e fa
next data 30 df 26 42 0a e9 44 da d9 5e ce d8 04 19 58 54 55 94 ad 1d f7 b8 e8 b9 0d e8 10 bc 66 b6 5f 99
next data f6 f4 ea 3f 75 97 3c 6e 74 8b d4 0b 8e 81 d4 41 3e a9 50 a2 2a ca c8 1a ca 8c 2d f9 6a 9e 8e 5a
next data 08 95 63 9a bc 70 12 b1 e2 35 20 57 56 dd 47 58 02 06 ab 53 ec 4a e6 30 1f b8 f6 36 55 3f 90 54
next data 90 68 f6 20 45 36 9f a0 84 8c 40 9c 2b 15 3c bb 43 6d a9 c9 3b b1 a8 52 42 ef 07 b8 d6 8c ec 4a
next data 6d 8e bc 40 a8 b3 91 e0 96 0a a7 ba 02 08 42 5e 8b 28 f6 0c 7f 8a 5e 6d 4c 50 30 9f 84 6e b1 83
next data e3 b7 34 9c 6d cd 41 25 2f f7 e9 c6 5c 66 0d ac 0a 79 af db 5f 60 04 24 96 2b db 9b 67 2a 84 4b
next data 08 84 ab 41 af fd d6 d6 92 1a 98 6d cf b4 cc 58 8a e3 35 68 34 b1 56 95 69 3d 68 93 b7 02 e3 49
next data 3c 44 ef 24 cf 23 57 8a 44 53 12 b2 95 e4 85 e5 ef 5e a5 f7 8f d9 23 a0 b7 20 86 7c e5 68 24 2b
next data 2e 27 2d f6 80 64 c6 75 05 45 67 b1 a3 c1 4b 97 99 d6 fc 20 2e 3c f8 ab a1 6e 67 8c 0b d7 cc 0a
next data f6 1b 33 ab 61 62 1a d6 5a 60 58 6c 0a e2 e0 44 bf cb 04 31 0d 22 2e 59 d9 06 c9 e8 f9 4a bc 97
next data ae db 73 cf 0b 12 39 c8 dd 51 8f f9 49 0d cc b2 22 b1 c6 02 8d c9 a9 13 a8 7d 83 bd 6b b3 fa 3f
next data 26 80 ab e5 47 2c 42 96 4d 33 9e 37 aa be fd 91 d5 e7 c7 b2 21 d8 d3 86 17 be 09 e4 ad 46 77 cf
next data 52 61 7f 11 29 d0 ec 51 33 32 a9 3f e8 da ff 5f 9d 83 34 d9 91 16 a5 9a f9 a4 48 61 b3 cd 7f 40
next data 09 5a 71 1a 95 8b 87 6d 17 60 c5 6e 21 be 34 db 1e dd 3f a1 92 aa ad 6a 4a bc cb d3 b5 98 5c e7
next data 9d 8b 15 1f 75 9e 02 49 f4 f1 74 02 73 57 ce 11 3e 6d d1 e4 55 1e 77 a3 c5 bb c6 08 2f 64 4d 72
next data ad dc 86 d5 67 43 ba 84 a5 a5 7c 13 ba 06 c7 5a d5 75 ad 4c 81 9d bd 52 9f 1f 3e 13 53 c6 89 a6
next data b6 7f 75 ee d7 d1 5d 45 8b bb cc 08 cd 8b a1 d8 5f 31 fc 45 af 45 78 4d f8 63 44 1f 50 5a 0e 74
next data f4 b2 9c e8 70 15 d6 0b f6 b9 c0 9a 69 75 fb 59 05 c4 7e b6 98 c9 da e6 fb 83 7d 24 f4 67 8a 29
next data 52 45 05 a5 01 f0 59 33 1e 47 b3 4b d6 80 e1 32 2e b7 ae 9c 70 7c 7e 4d 6d 3d 42 3c 01 e7 da e5
next data 3a c2 ee 5f ec 57 b0 e3 81 dc 6a 39 85 2d 45 2a 22 d6 71 aa af 27 e7 51 1b 2a 1e 76 90 1c 86 0d
next data b3 48 29 24 61 2c 14 7a 3c 4d 1f c6 fc a6 87 5f b1 e5 4a 7c e8 b1 2e 9a 19 9e 41 99 c8 00 4b e3
next data f5 29 05 43 38 5c b3 64 3a d5 6b 85 81 d3 84 ce ee 2f 8b 76 4c 4a b7 fd 8c 06 2e 8f bd 64 57 de
next data c7 c9 a4 76 63 b8 66 5b e1 83 bc da 45 31 94 4f a7 a3 a0 ec c2 cd 9e 1d a5 6a 8e a7 05 60 b1 3b
next data f4 21 f3 82 23 55 2e a6 df 63 83 2c 1a 36 b9 17 7f 99 f1 fa 63 c1 70 fc d8 ac d0 41 82 66 04 a9
next data 69 38 12 70 46 fa 6f 7e 3a 46 fc 5f 2b 0d d9 6f bb ee 7d 9a bf 82 60 56 79 e0 7f 7b b1 3d 89 ac
next data 35 34 74 f1 db 6b d0 f7 c9 39 51 20 1c 09 bf b6 89 ff 34 57 73 86 d5 02 72 fa 63 21 5b ae bf a8
next data 5f fc 44 0d 27 16 6b 4b ae e6 68 fb ff 04 00 4a e7 27 37 c8 5a 39 80 21 ef e3 d8 1f a5 e0 16 b2
next data f0 c7 9e 74 75 d3 7a c8 8b 14 45 47 4c 4f ff f7 7f 15 28 a3 5a d8 a9 c5 5c 7a 0e b5 9e 1c 21 ca
next data 63 43 ef 52 f6 93 40 96 57 78 d5 38 51 3a b7 82 9e db 60 71 17 56 52 2e b2 64 d7 df c2 c4 fb 92
next data 32 cc a6 eb cf 24 92 8d 6f 4f e1 8a 4e 79 2e 90 c6 9b c1 89 06 ab 72 8d ea 78 31 9a 11 53 83 7f
new key 4c 55 3e 80 03 fc 21 3a 4f 28 1e 60 a6 27 e5 3b 19 ed 52 1b 63 90 18 20 12 40 7d f7 dc d3 2a 73
data 2 63 06 2d 1a af 9e a9 38 f2 e4 c4 b7 4e 01 ec 6d 81 ed 33 b2 31 e1 57 e3 ac f9 ee 2d 3c 5d aa 4d
data 2 85 ca db b2 1f 49 ee fc 6a 54 6f 14 bb 86 7e e3 0e 6d cb 5c 52 fb 60 ae f7 94 84 5c 78 e1 6d 29
data 2 0b 78 1e 01 30 47 f1 a8 44 56 4e e2 4b a5 80 86 6d e6 e1 ff 4c 03 1d b5 53 e8 17 36 16 a9 33 55
data 2 ea 2e 91 99 4f 47 c5 8b 25 b0 e2 17 ea f0 a1 c0 83 3f 14 2a 20 3f 15 0c fb 0f 0f 59 d2 7a 79 68
data 2 1c af 7e a8 82 cd 47 24 8a d9 ed 01 a9 54 7e 96 f2 4f fb ba 58 ed bf 62 bc 38 82 9e ff cd 91 bd
data 2 e2 b3 82 81 5f 63 74 4a 27 bf d0 66 4e 78 17 54 5a 03 7f 93 85 8a 7c 89 30 ac 89 45 25 24 e0 a2
data 2 8f da 1d e1 d1 28 42 a6 45 99 1f 37 9b 97 39 9c 33 4b e5 d2 b5 48 13 6a a3 87 e8 b0 19 2a 44 35
data 2 c1 17 3e 3c fc 99 fe 8e 4a d8 bf 41 57 b0 20 f9 3b d0 c1 b8 9f 2f 27 70 11 0a df e1 cc 1a ec 3f
data 2 0c 4e 35 40 d2 14 76 cb 33 e9 0b 61 69 a0 82 39 4a 48 7e 59 b4 02 de 08 41 0b 20 37 e8 d2 2a b5
data 2 46 b4 55 1e 3f 24 48 41 ec 35 33 9d e0 f3 24 ce 68 84 4d db 5a 03 4c 5c 75 ba cb d2 b9 ba b5 b1
data 2 a5 7f 7b 1d e7 f6 80 fa 93 9e e5 a0 ec 99 15 d4 29 76 84 89 3d c9 02 0a 3e a5 af 15 49 6e c0 5d
data 2 a8 40 81 81 e2 f4 5b a6 94 04 81 90 c9 2d 0d 5e 3c 51 31 2b 0d a6 37 1f 48 a5 ee b9 86 9c 3c 7b
data 2 49 e3 c0 c4 77 d5 3e b6 0c a3 fe a7 0c e9 b3 26 17 13 e5 af e9 96 7c 00 ba 0f fc d0 fa f6 c2 be
data 2 f0 07 3d 89 72 45 ce ba af 62 f7 4a a9 4f 7f f5 2d cf 3d b3 bb e7 1e 46 8f 16 68 15 3f 89 96 69
data 2 02 79 77 47 61 7c ae 90 17 6e de 46 d7 f2 b7 ae ab fa 2e e3 44 3d 25 79 46 8f 18 02 94 08 ce 84
data 2 01 71 85 ef 0f 66 51 d7 0c 39 ab a1 ad 9e c3 dd d7 0f 15 3c 3f 9c e5 0a 5a 36 e7 01 a8 62 1a 6e
data 2 5b af 6f a6 1b 77 12 63 85 dd 72 56 31 b5 43 7a 2b b0 b6 8d a0 7c 22 d2 9f 2c 1d 72 0a 71 4a 86
data 2 7f b2 c7 03 a2 f9 d2 7b b0 a6 04 4f 1e 72 2b de 01 1c d6 11 6a 94 ba 59 0b a7 ec 6d 4d bb 7f b2
data 2 2e c9 dc c0 6e b1 4d c2 53 23 03 8c 1d 59 c9 c8 34 02 d1 17 50 34 8e 96 f7 44 d9 7a bb 7b 59 ff
data 2 6a 20 d5 7b 67 81 c6 af 08 b1 75 7f 2b f7 d6 1a 9e 3e 37 9b ef 62 6f 10 1a b2 56 05 13 ea 19 ff
data 2 07 ed e0 eb 1a d4 1f 90 9a 2e 11 b1 73 ac cd 2d 6a 69 99 ed 33 e2 bf 1f bf 9d 0f dc e3 c8 26 25
data 2 dc 99 58 46 cc 22 8e 01 81 03 b5 4e 36 90 c9 1f e4 2b 7e 15 da 18 9f 5e ee 57 d3 34 ba 24 f7 57
data 2 c4 23 a0 87 03 ff b2 23 46 8f e3 1b 28 f3 c9 5d 01 3d 51 29 89 fe 32 dd ca 39 0f 64 68 cc 7c 34
data 2 d8 e1 b5 d0 8e 6b c8 31 88 ac 95 59 ac 81 9a 98 78 49 2d 7a c7 c7 68 78 94 98 21 33 ac 55 56 4f
data 2 3c 2c 29 ac 3e 37 ec 52 7f 4a 97 e4 ec 96 4f d2 4f 9a c9 65 fd 12 95 6c ab 5a ed 6e af c9 ee 9f
data 2 23 28 73 7d da 6c 8a 15 d1 ae 54 2e 51 7b 3a 27 fd c8 12 98 ad 54 65 4b 0e d3 f9 a1 d6 1b ab 99
data 2 71 a1 27 ee 2d 09 f5 6e e3 02 d1 14 79 db 49 b9 a0 e7 74 31 b1 62 4f 4f ac 05 06 2f 3f 16 e6 67
data 2 4b a2 78 b6 cc 0f e5 1e 78 0d bd b5 c9 aa cd 22 31 74 80 28 12 f2 90 d8 a4 d2 1d 5c 74 5a 18 13
data 2 b2 3f bd f4 8b 97 1b 7a 6b e5 fc 65 a7 a4 91 ab b3 a0 c6 8a a6 4b 8b 8b 6f 74 53 bb 0f 06 bb 42
data 2 bc b7 fb 5d 60 15 40 a1 a9 a2 1c 6d c2 76 23 09 84 07 ce c4 df 2a 59 19 32 2e 18 4c ab 29 0b aa
data 2 ed 2f dc 10 91 6a f9 c4 bc 1b d8 71 92 aa d5 af f9 dd 3d b5 be 82 4a e9 9b af 4c 14 94 53 bc a0
data 2 1a 72 98 95 7f 09 e8 74 2f f2 b6 b8 5d ef 7a 35 12 e8 2f 2d 2a 23 96 07 ea 39 e8 5b 6d 79 4d f7
data 2 a9 6b c1 2e c0 5c 68 f8 6b 31 95 c7 91 78 f7 15 1d 00 8e fd 18 9a e0 d5 fe da f1 5b 05 80 c5 fc
data 2 aa 2c 35 1b 08 b3 b8 a6 a4 cc 28 5c fc 11 4c 90 91 55 fa 52 01 79 1e 0f 05 c5 6e 4a 5c 1b 3e fa
data 2 30 df 26 42 0a e9 44 da d9 5e ce d8 04 19 58 54 55 94 ad 1d f7 b8 e8 b9 0d e8 10 bc 66 b6 5f 99
data 2 f6 f4 ea 3f 75 97 3c 6e 74 8b d4 0b 8e 81 d4 41 3e a9 50 a2 2a ca c8 1a ca 8c 2d f9 6a 9e 8e 5a
data 2 08 95 63 9a bc 70 12 b1 e2 35 20 57 56 dd 47 58 02 06 ab 53 ec 4a e6 30 1f b8 f6 36 55 3f 90 54
data 2 90 68 f6 20 45 36 9f a0 84 8c 40 9c 2b 15 3c bb 43 6d a9 c9 3b b1 a8 52 42 ef 07 b8 d6 8c ec 4a
data 2 6d 8e bc 40 a8 b3 91 e0 96 0a a7 ba 02 08 42 5e 8b 28 f6 0c 7f 8a 5e 6d 4c 50 30 9f 84 6e b1 83
data 2 e3 b7 34 9c 6d cd 41 25 2f f7 e9 c6 5c 66 0d ac 0a 79 af db 5f 60 04 24 96 2b db 9b 67 2a 84 4b
data 2 08 84 ab 41 af fd d6 d6 92 1a 98 6d cf b4 cc 58 8a e3 35 68 34 b1 56 95 69 3d 68 93 b7 02 e3 49
data 2 3c 44 ef 24 cf 23 57 8a 44 53 12 b2 95 e4 85 e5 ef 5e a5 f7 8f d9 23 a0 b7 20 86 7c e5 68 24 2b
data 2 2e 27 2d f6 80 64 c6 75 05 45 67 b1 a3 c1 4b 97 99 d6 fc 20 2e 3c f8 ab a1 6e 67 8c 0b d7 cc 0a
data 2 f6 1b 33 ab 61 62 1a d6 5a 60 58 6c 0a e2 e0 44 bf cb 04 31 0d 22 2e 59 d9 06 c9 e8 f9 4a bc 97
data 2 ae db 73 cf 0b 12 39 c8 dd 51 8f f9 49 0d cc b2 22 b1 c6 02 8d c9 a9 13 a8 7d 83 bd 6b b3 fa 3f
data 2 26 80 ab e5 47 2c 42 96 4d 33 9e 37 aa be fd 91 d5 e7 c7 b2 21 d8 d3 86 17 be 09 e4 ad 46 77 cf
data 2 52 61 7f 11 29 d0 ec 51 33 32 a9 3f e8 da ff 5f 9d 83 34 d9 91 16 a5 9a f9 a4 48 61 b3 cd 7f 40
data 2 09 5a 71 1a 95 8b 87 6d 17 60 c5 6e 21 be 34 db 1e dd 3f a1 92 aa ad 6a 4a bc cb d3 b5 98 5c e7
data 2 9d 8b 15 1f 75 9e 02 49 f4 f1 74 02 73 57 ce 11 3e 6d d1 e4 55 1e 77 a3 c5 bb c6 08 2f 64 4d 72
data 2 ad dc 86 d5 67 43 ba 84 a5 a5 7c 13 ba 06 c7 5a d5 75 ad 4c 81 9d bd 52 9f 1f 3e 13 53 c6 89 a6
data 2 b6 7f 75 ee d7 d1 5d 45 8b bb cc 08 cd 8b a1 d8 5f 31 fc 45 af 45 78 4d f8 63 44 1f 50 5a 0e 74
data 2 f4 b2 9c e8 70 15 d6 0b f6 b9 c0 9a 69 75 fb 59 05 c4 7e b6 98 c9 da e6 fb 83 7d 24 f4 67 8a 29
data 2 52 45 05 a5 01 f0 59 33 1e 47 b3 4b d6 80 e1 32 2e b7 ae 9c 70 7c 7e 4d 6d 3d 42 3c 01 e7 da e5
data 2 3a c2 ee 5f ec 57 b0 e3 81 dc 6a 39 85 2d 45 2a 22 d6 71 aa af 27 e7 51 1b 2a 1e 76 90 1c 86 0d
data 2 b3 48 29 24 61 2c 14 7a 3c 4d 1f c6 fc a6 87 5f b1 e5 4a 7c e8 b1 2e 9a 19 9e 41 99 c8 00 4b e3
data 2 f5 29 05 43 38 5c b3 64 3a d5 6b 85 81 d3 84 ce ee 2f 8b 76 4c 4a b7 fd 8c 06 2e 8f bd 64 57 de
data 2 c7 c9 a4 76 63 b8 66 5b e1 83 bc da 45 31 94 4f a7 a3 a0 ec c2 cd 9e 1d a5 6a 8e a7 05 60 b1 3b
data 2 f4 21 f3 82 23 55 2e a6 df 63 83 2c 1a 36 b9 17 7f 99 f1 fa 63 c1 70 fc d8 ac d0 41 82 66 04 a9
data 2 69 38 12 70 46 fa 6f 7e 3a 46 fc 5f 2b 0d d9 6f bb ee 7d 9a bf 82 60 56 79 e0 7f 7b b1 3d 89 ac
data 2 35 34 74 f1 db 6b d0 f7 c9 39 51 20 1c 09 bf b6 89 ff 34 57 73 86 d5 02 72 fa 63 21 5b ae bf a8
data 2 5f fc 44 0d 27 16 6b 4b ae e6 68 fb ff 04 00 4a e7 27 37 c8 5a 39 80 21 ef e3 d8 1f a5 e0 16 b2
data 2 f0 c7 9e 74 75 d3 7a c8 8b 14 45 47 4c 4f ff f7 7f 15 28 a3 5a d8 a9 c5 5c 7a 0e b5 9e 1c 21 ca
data 2 63 43 ef 52 f6 93 40 96 57 78 d5 38 51 3a b7 82 9e db 60 71 17 56 52 2e b2 64 d7 df c2 c4 fb 92
data 2 32 cc a6 eb cf 24 92 8d 6f 4f e1 8a 4e 79 2e 90 c6 9b c1 89 06 ab 72 8d ea 78 31 9a 11 53 83 7f
00000 63062d1aaf9ea938f2e4c4b74e01ec6d81ed33b231e157e3acf9ee2d3c5daa4d
00001 85cadbb21f49eefc6a546f14bb867ee30e6dcb5c52fb60aef794845c78e16d29
00002 0b781e013047f1a844564ee24ba580866de6e1ff4c031db553e8173616a93355
00003 ea2e91994f47c58b25b0e217eaf0a1c0833f142a203f150cfb0f0f59d27a7968
00004 1caf7ea882cd47248ad9ed01a9547e96f24ffbba58edbf62bc38829effcd91bd
00005 e2b382815f63744a27bfd0664e7817545a037f93858a7c8930ac89452524e0a2
00006 8fda1de1d12842a645991f379b97399c334be5d2b548136aa387e8b0192a4435
00007 c1173e3cfc99fe8e4ad8bf4157b020f93bd0c1b89f2f2770110adfe1cc1aec3f
00008 0c4e3540d21476cb33e90b6169a082394a487e59b402de08410b2037e8d22ab5
00009 46b4551e3f244841ec35339de0f324ce68844ddb5a034c5c75bacbd2b9bab5b1
Dieharder testilista ressu2:sta: Mielestäni tämä on dieharder ok, ei failed:eja ja vähän weak:keja suurissa tiedostoissa.
'input' = "ressu2", 'filesize' = "500m", 'filename' = "newressusample2738.rnd", 'weak' = "1", 'failed' = "1"
'input' = "ressu2", 'filesize' = "600m", 'filename' = "newressusample2739.rnd", 'weak' = "5", 'failed' = "0"
'input' = "ressu2", 'filesize' = "700m", 'filename' = "newressusample2740.rnd", 'weak' = "5", 'failed' = "1"
'input' = "ressu2", 'filesize' = "800m", 'filename' = "newressusample2741.rnd", 'weak' = "3", 'failed' = "1"
'input' = "ressu2", 'filesize' = "900m", 'filename' = "newressusample2742.rnd", 'weak' = "5", 'failed' = "3"
'input' = "ressu2", 'filesize' = "1g", 'filename' = "newressusample2743.rnd", 'weak' = "7", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g100m", 'filename' = "newressusample2744.rnd", 'weak' = "2", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g200m", 'filename' = "newressusample2745.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g300m", 'filename' = "newressusample2746.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g400m", 'filename' = "newressusample2747.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g500m", 'filename' = "newressusample2748.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g600m", 'filename' = "newressusample2749.rnd", 'weak' = "2", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g700m", 'filename' = "newressusample2750.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g800m", 'filename' = "newressusample2751.rnd", 'weak' = "5", 'failed' = "0"
'input' = "ressu2", 'filesize' = "1g900m", 'filename' = "newressusample2752.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2", 'filesize' = "2g", 'filename' = "newressusample2753.rnd", 'weak' = "5", 'failed' = "0"
'input' = "ressu2", 'filesize' = "3g", 'filename' = "newressusample2754.rnd", 'weak' = "1", 'failed' = "0"
'input' = "ressu2", 'filesize' = "4g", 'filename' = "newressusample2755.rnd", 'weak' = "2", 'failed' = "0"
'input' = "ressu2", 'filesize' = "5g", 'filename' = "newressusample2756.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2", 'filesize' = "6g", 'filename' = "newressusample2757.rnd", 'weak' = "1", 'failed' = "0"
Dieharder testilista pseudoressu2:sta: Ok, ei failedeja ja vähän weakkeja suurissa tiedostoissa.
'input' = "pseudoressu2", 'filesize' = "500m", 'filename' = "newressusample2758.rnd", 'weak' = "5", 'failed' = "2"
'input' = "pseudoressu2", 'filesize' = "600m", 'filename' = "newressusample2759.rnd", 'weak' = "7", 'failed' = "2"
'input' = "pseudoressu2", 'filesize' = "700m", 'filename' = "newressusample2760.rnd", 'weak' = "10", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "800m", 'filename' = "newressusample2761.rnd", 'weak' = "8", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "900m", 'filename' = "newressusample2762.rnd", 'weak' = "7", 'failed' = "1"
'input' = "pseudoressu2", 'filesize' = "1g", 'filename' = "newressusample2763.rnd", 'weak' = "4", 'failed' = "1"
'input' = "pseudoressu2", 'filesize' = "1g100m", 'filename' = "newressusample2764.rnd", 'weak' = "6", 'failed' = "1"
'input' = "pseudoressu2", 'filesize' = "1g200m", 'filename' = "newressusample2765.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g300m", 'filename' = "newressusample2766.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g400m", 'filename' = "newressusample2767.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g500m", 'filename' = "newressusample2768.rnd", 'weak' = "5", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g600m", 'filename' = "newressusample2769.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g700m", 'filename' = "newressusample2770.rnd", 'weak' = "0", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g800m", 'filename' = "newressusample2771.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "1g900m", 'filename' = "newressusample2772.rnd", 'weak' = "6", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "2g", 'filename' = "newressusample2773.rnd", 'weak' = "1", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "3g", 'filename' = "newressusample2774.rnd", 'weak' = "3", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "4g", 'filename' = "newressusample2775.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "5g", 'filename' = "newressusample2776.rnd", 'weak' = "2", 'failed' = "0"
'input' = "pseudoressu2", 'filesize' = "6g", 'filename' = "newressusample2777.rnd", 'weak' = "3", 'failed' = "0"
Satunnaisuutta uudella ressu2 generaattorilla:
$ ./newressu --ressu2
00000 55949688185877341622034227541378358620539934130837719664015749825
00001 90609858998821602441917202808264534591287578077989136742900866080
00002 44653972246055646517940661857889194466575890077315426625709155915
00003 67192606200278134817302551033244679217156733269282593200465683983
00004 92283856703758594911481763394520065118335172424598538245141590298
00005 81558071505005214523849322816760347941979957346210881138886861597
00006 59329345032375251938529864753832947412048701642443981621813623435
00007 80735336479573969714887797856894161601026714700327709748079022917
00008 75142788258848392567725240728823059014103521671163205098204149287
00009 22441185654701012226687325620374115145811551877672491908751449959
$
Satunnaisuutta uudella pseudoressu2 näennäissatunnaisuus generaattorilla:
$ ./newressu --pseudoressu2
00000 85210990573137512871005264801811199128654491886808034736163554942
00001 64677471450469966354556116443957044953612856759130486473464062854
00002 55244260728363247309374816485489944044493198417291953615626399619
00003 71292874050633453141233297472991712853023376958941974807812080103
00004 34509835550310579452057636862600360312461549749456733846768208549
00005 65298151149519225524699319280380167673174291326237248090305622325
00006 68128129924712407267106195675494141759175901350086966935584953448
00007 41420779725606729561488118631320851280250181394020744538481864768
00008 87138036750865155818189866099580945219878546245583604713529755468
00009 38170466736607134528385105717567122125263260887214944577702022407
$
ressu2twist yhdistää kaksi edellistä, ja sen pitäisi tehdä kellojonon arvaaminan vaikeammaksi, jos ei mahdottomaksi:
void ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023
{
ressu2_bytes(size, buffer);
pseudoressu2_bytes(size, buffer);
#ifdef DEBUG17
ressu_dump("data 3", size, buffer, 32);
#endif
}
Seuraavana DEBUG17 testilista –ressu2twist:stä: Uutena tässä listassa data 3 -rivit, jotka ovat ressu2twist:in palauttamia rivejä.
$ ./newressu --ressu2twist -x
ressu2 6b e5 ae c4 49 f3 fe 52 e9 1a 11 40 96 56 b4 06 8a 19 3f b6 1e da 39 f4 f6 e8 09 0a d0 4a 84 c5
ressu2 3c 7f 0b b6 0d 57 8b 93 56 72 80 f7 87 4a 26 a4 fb d5 9f ac bc 5c 1a 73 f0 54 cf c5 ed 23 48 f7
ressu2 7d 8a c9 e9 f9 72 58 39 ab 6f b6 8c 60 89 6a 1c bb 77 09 15 f2 56 ca c6 07 c3 82 90 c3 83 04 9d
ressu2 21 57 16 94 b5 5c 18 c7 18 99 16 57 06 4c e9 18 b5 36 5b fd 37 9e 32 e1 b7 9f ec cb 8f f3 6b c8
ressu2 a5 15 c7 36 c0 ca ea af f2 09 68 b5 cb 49 bb 55 ef 3d 8e 10 cc ae 63 81 de 7c 35 a0 0b 56 d5 3f
ressu2 1c 5f b9 6e d9 b9 79 89 12 d0 14 a8 c7 c6 45 03 fa 89 13 23 23 52 63 5b 39 0e 6c 6d a4 bd 86 7d
ressu2 f4 74 71 66 90 ef 50 2e d2 bd 9d e3 47 1e 46 b2 f5 57 79 d7 91 14 50 05 fb 7f d1 fc f1 0a 5f 69
ressu2 12 a7 01 5a 6a 69 bb c7 91 93 4c 3d 26 48 9c fb b6 d6 0f 21 13 73 f9 af ec 46 c0 5d f6 8c 88 f1
ressu2 7a 43 3b b2 ab 91 fd 8b 7b a1 f4 c0 25 35 e9 03 c7 ef b2 8e b2 4e 04 c4 ac 90 f8 18 b7 fd 5b 4f
ressu2 f8 ad 59 75 ae d6 ce b5 31 65 89 2c 49 ee b3 4f 7d 8f 77 cd 72 0d 22 3f 30 95 af 65 7e 6c 48 fa
ressu2 93 60 56 a5 37 16 57 da 15 b8 82 00 67 59 d8 1e 20 39 73 4a 46 62 ce 6e f5 46 6e 28 7c 0f 0c e8
ressu2 cf 27 77 59 07 12 b3 5f 3d 8e a1 c5 c9 d5 f6 c4 a6 f8 af 3b b4 ec b7 39 04 7e d6 bf 20 a3 14 cd
ressu2 ff 45 f7 c9 20 6f 27 61 c6 32 50 e0 f8 ba 87 dc 20 4d de 5c c8 65 c3 99 ce 3f 9a 2d 2b 87 89 da
ressu2 75 78 6d a5 d4 92 06 9c 77 95 7a 15 f5 6c 49 60 d7 12 6b e5 fa d8 a9 a1 5e 95 a3 c3 67 c8 75 bc
ressu2 20 87 1c ed 23 9f df cc 8a d0 bd 22 21 c9 72 4c 46 3a 97 ea 0e 96 66 90 80 7f 31 42 57 67 6b 1a
ressu2 5c ff 4f c8 48 17 4c d4 2b ec 8b 41 17 d6 b2 ee 62 b8 bc 3c f4 8f 0d 1d 40 0d 68 0c cc ff 8a 2a
ressu2 b3 27 de cd bc 99 f0 7f 79 44 56 aa dd a5 69 19 93 4f 08 ed ac e7 6c 1b db 60 36 d8 9c 80 23 23
ressu2 67 ba 81 38 e7 79 7d 42 9e 92 70 d0 a3 84 91 d2 54 1b a5 a6 26 71 1b 5d e9 ea 99 4b 69 24 f5 52
ressu2 ea 6a 21 1c cb 64 ed 83 80 52 18 0d a2 86 5a 95 85 9f 2c c0 ef 71 b3 a7 9e ad 79 33 25 3b 0d bc
ressu2 90 80 1c f4 ef 6a a9 f6 29 00 95 a7 00 e9 06 ea cb ac df 08 d1 b8 d0 1b f0 88 e7 75 c6 18 25 51
ressu2 63 31 ae ec ca 8e fd 69 5e 0b 5a 35 a5 88 be fe ca f9 2c c2 79 03 0e 45 5e 96 c5 31 c9 7b 8d 85
ressu2 6e 06 e5 ba 3b d4 a2 af 94 ff c0 57 aa 99 29 9c 15 18 e7 09 bf a0 5e fa 07 05 36 d7 b1 57 99 f8
ressu2 9f 09 e6 4d 79 bf 0b a8 4e 9e 05 55 c6 91 71 b0 e5 3d 94 03 84 35 fa 2b 74 c1 0c 4a 7f 38 bc a6
ressu2 ca a0 9d b6 ab 41 84 fc d6 60 93 0b 64 78 af f7 a3 90 f8 0f c6 cb 6b 03 e8 25 18 30 3b 73 66 5d
ressu2 cf 51 01 ac fc ab 11 00 dd 5b 75 59 56 99 10 c4 40 89 fa ca cf 5f 6a ed b3 54 3f 28 71 9c 4b 9c
ressu2 a4 da f0 69 5f 0c 9a 78 42 bd 46 4b de 83 db 7a 9f 50 d1 ec ab c4 6d e2 f2 bf 59 6a fe ef d2 31
ressu2 74 75 32 f5 f6 7c bb f4 d5 ad 04 e4 2a c9 e8 32 b1 b1 cf 94 eb 98 a7 4a c2 d0 83 eb 9f 6e 3a 83
ressu2 86 58 34 cd 79 9b 04 85 ee 2f c2 51 29 fa b8 4b 40 19 1c 0f 05 85 ba 04 4b 84 30 ae 2e c4 0f 17
ressu2 86 c8 14 8e 91 77 fe 3b 11 30 5d c6 78 be 85 f4 c9 d5 d9 ac c7 76 0b 22 24 dd 2d 5e c9 17 88 ad
ressu2 d4 f5 20 7d 38 e1 b7 86 57 4d e4 7f 3f 6c 42 d1 12 d0 c4 73 0b e8 84 e8 b9 e6 f5 6f ed ef dc 0b
ressu2 fc 4e 5e 5c 0e 8a b9 be 04 a3 02 68 e2 e8 48 bb 04 30 a9 26 b1 16 74 9d 26 b8 8d bc 66 64 88 23
ressu2 7a 6a 67 a0 c3 66 b1 97 c7 97 74 af c1 09 b2 03 0a 08 20 1d ab 40 3e a5 9a db cf 97 31 fe 04 73
ressu2 f6 50 f8 24 d7 c7 af f7 8c d7 22 39 46 85 83 d9 92 b6 63 49 04 2b 65 cf a6 c9 b0 b8 55 6c 26 37
ressu2 3f 98 ba d6 e0 29 d4 be 68 ed 42 a1 83 b2 a7 db e4 f3 b4 2e d6 3d 93 cc 35 e1 11 d3 e2 8a c6 62
ressu2 3b 85 a6 e4 c6 84 47 57 7c 9d af 6f 79 9e 9e e3 e2 2e be 91 20 ae f5 ea ba 9b a5 d9 09 0f 97 07
ressu2 5c 6c 75 ea ba 46 8d 83 e3 ad 3f 31 1b b2 84 a5 db a3 5b 81 f0 b0 03 ac ed 5a d8 88 d5 2c 1a 85
ressu2 6a 8b 18 85 58 57 8c c0 c8 01 d3 8a e4 79 fb 16 3c a6 18 c7 fb 56 de 53 bf 24 74 bc 74 bb e2 40
ressu2 68 ff 05 f2 11 6a 1c e9 e7 9a f9 39 5b c4 ea 21 89 3a d3 19 d1 c7 da 16 46 d5 7e e5 bd 4c f0 e4
ressu2 57 f9 22 b4 95 a3 10 96 0b 9e b8 d6 7b 73 3e b1 80 1a d1 9b 31 8b 85 2c 0d 63 68 7f d8 78 9b b6
ressu2 a0 c1 8b 86 dc 88 8b 0e 7b a6 91 02 98 ee 6d 14 72 ae 86 6e 93 d1 70 34 32 3c 45 02 6f 9a 51 d9
ressu2 60 bb 99 71 5b db 36 9e d2 92 d8 73 dd 05 a0 32 a2 83 65 47 e7 c5 1d 0c fe 2d 8d 38 1d f1 b0 13
ressu2 0b d3 27 66 f6 d3 2b fd ac 12 3d 02 90 2b 19 ea ba 05 68 5b d7 75 21 d6 a9 8b 18 2e d4 5e bc b5
ressu2 b3 b1 72 bd 7e 9c 5c c3 ae 20 e0 40 b1 aa f6 6d 06 d5 e4 25 99 50 83 29 c8 1a 2d 0f d8 bb 34 34
ressu2 b7 08 02 0a b6 50 7e 18 5c 87 4b db 88 69 b4 91 23 70 d0 2c 1a 63 f9 2b 17 39 ce ba 16 a8 27 8c
ressu2 b3 ed 62 ed a1 0e 21 13 1b a3 4f ff 87 30 71 87 5c b6 e2 4d f2 ab 8f 8d d0 e6 04 45 90 41 4d 2c
ressu2 f4 dd c4 37 55 40 d0 ed 04 29 6f 82 57 a3 15 1f 39 b0 d2 b7 c2 84 54 a3 01 e3 8a 11 83 b6 1a c2
ressu2 58 d2 54 e0 73 cc e3 76 99 d3 10 a3 37 21 34 93 ff 77 2e cf a6 cb 64 02 6f 19 4e a5 67 84 a3 7b
ressu2 28 2e b3 25 0f 4e 7a eb e6 45 fd 26 90 b1 05 74 cd a3 29 5f f9 f8 ad 6d 50 d7 cf 85 68 f0 29 c6
ressu2 92 c9 24 06 4e 84 0c de 96 e9 1f 63 01 98 a2 a6 ef f7 d9 87 91 cf 8b 3d c7 26 41 2a bb be 80 39
ressu2 11 e3 71 a5 b8 be 43 3a 1d d6 45 a4 59 b3 28 80 16 9a fb b0 51 b4 19 ff 2f 81 df e7 84 ff 0d a8
ressu2 45 ce 58 0e 6e fa 5d fb 7d e4 e7 27 3a b0 8e dd 9e 97 e2 e5 31 90 2d 3f 85 6f 9e 3f f1 0c aa 15
ressu2 d9 92 c7 db 6c 21 d7 65 3d 72 a2 97 29 3b 38 cb 35 82 8b cd 44 d3 55 51 65 5e 0c fb 67 a6 ee a7
ressu2 aa 28 84 9c 91 75 db e5 2d e9 d5 2b 7c 85 ad f0 fb 9f 8d c5 70 37 a1 4c a7 94 81 1a 08 b5 cf 32
ressu2 b1 03 9a 87 ec 9f c7 ad 2f f3 50 ab 62 05 9b d6 34 03 7f 6a 3d 8b 1f 97 c1 7c 95 0f c9 5a df c9
ressu2 e0 35 a2 9c 30 7f e9 95 fc aa 2d c3 0c 08 ac 34 ca 7f ff aa e7 61 6b 03 5d 90 23 cd 07 cd 34 41
ressu2 e9 ca 7e 0c 5a f3 58 b3 df 7a f9 d0 68 2f bf e6 d1 35 84 42 60 b3 41 ef cd c1 26 04 fe 97 4a 8b
ressu2 e2 e2 d1 93 f1 f7 da 7a 79 ce 55 c5 9f e6 96 b4 0d 4d 0a bf fe 4e 5c cd ab 47 1b 0a ef 09 81 2f
ressu2 99 74 5f 83 02 0a ed 08 ef 08 4c 01 9d cb 79 b4 86 31 ab 9d d6 dc 55 71 c2 ce 6f 10 86 36 15 54
ressu2 f5 07 53 6b c4 ed 16 56 04 50 e0 66 4c 87 01 dd a7 93 49 28 ce 29 6c ab 96 f7 88 f2 78 07 4e ad
ressu2 fd 36 96 c0 ee 26 d5 37 e6 99 13 28 58 b7 64 31 78 54 e1 86 9f 73 8d a1 4a a6 97 1d 3f 86 7d ef
ressu2 2a df 1a e8 03 84 60 70 a7 99 bc a5 fb bb 45 dd 17 3e e6 ac 44 1e 9a cd c2 c2 68 cb 5a b4 d8 bc
ressu2 78 1d 29 7d 19 72 81 dc 17 37 56 30 5a 68 71 16 cf ed c2 61 43 9f 52 10 0b 7e 48 ee cc 32 a1 d4
ressu2 da 94 bd 2a 82 63 8e 57 97 fc 98 e8 c3 c5 29 18 d7 9e 00 07 be 82 aa 10 0f b7 52 03 45 ed f3 95
ressu2 79 c7 64 d6 ac ed 0e b7 6b 4f 14 d2 8f 17 c1 77 f3 41 a9 37 47 b2 53 b3 68 f8 2f b7 84 2e 4c e4
data 1 6b e5 ae c4 49 f3 fe 52 e9 1a 11 40 96 56 b4 06 8a 19 3f b6 1e da 39 f4 f6 e8 09 0a d0 4a 84 c5
data 1 3c 7f 0b b6 0d 57 8b 93 56 72 80 f7 87 4a 26 a4 fb d5 9f ac bc 5c 1a 73 f0 54 cf c5 ed 23 48 f7
data 1 7d 8a c9 e9 f9 72 58 39 ab 6f b6 8c 60 89 6a 1c bb 77 09 15 f2 56 ca c6 07 c3 82 90 c3 83 04 9d
data 1 21 57 16 94 b5 5c 18 c7 18 99 16 57 06 4c e9 18 b5 36 5b fd 37 9e 32 e1 b7 9f ec cb 8f f3 6b c8
data 1 a5 15 c7 36 c0 ca ea af f2 09 68 b5 cb 49 bb 55 ef 3d 8e 10 cc ae 63 81 de 7c 35 a0 0b 56 d5 3f
data 1 1c 5f b9 6e d9 b9 79 89 12 d0 14 a8 c7 c6 45 03 fa 89 13 23 23 52 63 5b 39 0e 6c 6d a4 bd 86 7d
data 1 f4 74 71 66 90 ef 50 2e d2 bd 9d e3 47 1e 46 b2 f5 57 79 d7 91 14 50 05 fb 7f d1 fc f1 0a 5f 69
data 1 12 a7 01 5a 6a 69 bb c7 91 93 4c 3d 26 48 9c fb b6 d6 0f 21 13 73 f9 af ec 46 c0 5d f6 8c 88 f1
data 1 7a 43 3b b2 ab 91 fd 8b 7b a1 f4 c0 25 35 e9 03 c7 ef b2 8e b2 4e 04 c4 ac 90 f8 18 b7 fd 5b 4f
data 1 f8 ad 59 75 ae d6 ce b5 31 65 89 2c 49 ee b3 4f 7d 8f 77 cd 72 0d 22 3f 30 95 af 65 7e 6c 48 fa
data 1 93 60 56 a5 37 16 57 da 15 b8 82 00 67 59 d8 1e 20 39 73 4a 46 62 ce 6e f5 46 6e 28 7c 0f 0c e8
data 1 cf 27 77 59 07 12 b3 5f 3d 8e a1 c5 c9 d5 f6 c4 a6 f8 af 3b b4 ec b7 39 04 7e d6 bf 20 a3 14 cd
data 1 ff 45 f7 c9 20 6f 27 61 c6 32 50 e0 f8 ba 87 dc 20 4d de 5c c8 65 c3 99 ce 3f 9a 2d 2b 87 89 da
data 1 75 78 6d a5 d4 92 06 9c 77 95 7a 15 f5 6c 49 60 d7 12 6b e5 fa d8 a9 a1 5e 95 a3 c3 67 c8 75 bc
data 1 20 87 1c ed 23 9f df cc 8a d0 bd 22 21 c9 72 4c 46 3a 97 ea 0e 96 66 90 80 7f 31 42 57 67 6b 1a
data 1 5c ff 4f c8 48 17 4c d4 2b ec 8b 41 17 d6 b2 ee 62 b8 bc 3c f4 8f 0d 1d 40 0d 68 0c cc ff 8a 2a
data 1 b3 27 de cd bc 99 f0 7f 79 44 56 aa dd a5 69 19 93 4f 08 ed ac e7 6c 1b db 60 36 d8 9c 80 23 23
data 1 67 ba 81 38 e7 79 7d 42 9e 92 70 d0 a3 84 91 d2 54 1b a5 a6 26 71 1b 5d e9 ea 99 4b 69 24 f5 52
data 1 ea 6a 21 1c cb 64 ed 83 80 52 18 0d a2 86 5a 95 85 9f 2c c0 ef 71 b3 a7 9e ad 79 33 25 3b 0d bc
data 1 90 80 1c f4 ef 6a a9 f6 29 00 95 a7 00 e9 06 ea cb ac df 08 d1 b8 d0 1b f0 88 e7 75 c6 18 25 51
data 1 63 31 ae ec ca 8e fd 69 5e 0b 5a 35 a5 88 be fe ca f9 2c c2 79 03 0e 45 5e 96 c5 31 c9 7b 8d 85
data 1 6e 06 e5 ba 3b d4 a2 af 94 ff c0 57 aa 99 29 9c 15 18 e7 09 bf a0 5e fa 07 05 36 d7 b1 57 99 f8
data 1 9f 09 e6 4d 79 bf 0b a8 4e 9e 05 55 c6 91 71 b0 e5 3d 94 03 84 35 fa 2b 74 c1 0c 4a 7f 38 bc a6
data 1 ca a0 9d b6 ab 41 84 fc d6 60 93 0b 64 78 af f7 a3 90 f8 0f c6 cb 6b 03 e8 25 18 30 3b 73 66 5d
data 1 cf 51 01 ac fc ab 11 00 dd 5b 75 59 56 99 10 c4 40 89 fa ca cf 5f 6a ed b3 54 3f 28 71 9c 4b 9c
data 1 a4 da f0 69 5f 0c 9a 78 42 bd 46 4b de 83 db 7a 9f 50 d1 ec ab c4 6d e2 f2 bf 59 6a fe ef d2 31
data 1 74 75 32 f5 f6 7c bb f4 d5 ad 04 e4 2a c9 e8 32 b1 b1 cf 94 eb 98 a7 4a c2 d0 83 eb 9f 6e 3a 83
data 1 86 58 34 cd 79 9b 04 85 ee 2f c2 51 29 fa b8 4b 40 19 1c 0f 05 85 ba 04 4b 84 30 ae 2e c4 0f 17
data 1 86 c8 14 8e 91 77 fe 3b 11 30 5d c6 78 be 85 f4 c9 d5 d9 ac c7 76 0b 22 24 dd 2d 5e c9 17 88 ad
data 1 d4 f5 20 7d 38 e1 b7 86 57 4d e4 7f 3f 6c 42 d1 12 d0 c4 73 0b e8 84 e8 b9 e6 f5 6f ed ef dc 0b
data 1 fc 4e 5e 5c 0e 8a b9 be 04 a3 02 68 e2 e8 48 bb 04 30 a9 26 b1 16 74 9d 26 b8 8d bc 66 64 88 23
data 1 7a 6a 67 a0 c3 66 b1 97 c7 97 74 af c1 09 b2 03 0a 08 20 1d ab 40 3e a5 9a db cf 97 31 fe 04 73
data 1 f6 50 f8 24 d7 c7 af f7 8c d7 22 39 46 85 83 d9 92 b6 63 49 04 2b 65 cf a6 c9 b0 b8 55 6c 26 37
data 1 3f 98 ba d6 e0 29 d4 be 68 ed 42 a1 83 b2 a7 db e4 f3 b4 2e d6 3d 93 cc 35 e1 11 d3 e2 8a c6 62
data 1 3b 85 a6 e4 c6 84 47 57 7c 9d af 6f 79 9e 9e e3 e2 2e be 91 20 ae f5 ea ba 9b a5 d9 09 0f 97 07
data 1 5c 6c 75 ea ba 46 8d 83 e3 ad 3f 31 1b b2 84 a5 db a3 5b 81 f0 b0 03 ac ed 5a d8 88 d5 2c 1a 85
data 1 6a 8b 18 85 58 57 8c c0 c8 01 d3 8a e4 79 fb 16 3c a6 18 c7 fb 56 de 53 bf 24 74 bc 74 bb e2 40
data 1 68 ff 05 f2 11 6a 1c e9 e7 9a f9 39 5b c4 ea 21 89 3a d3 19 d1 c7 da 16 46 d5 7e e5 bd 4c f0 e4
data 1 57 f9 22 b4 95 a3 10 96 0b 9e b8 d6 7b 73 3e b1 80 1a d1 9b 31 8b 85 2c 0d 63 68 7f d8 78 9b b6
data 1 a0 c1 8b 86 dc 88 8b 0e 7b a6 91 02 98 ee 6d 14 72 ae 86 6e 93 d1 70 34 32 3c 45 02 6f 9a 51 d9
data 1 60 bb 99 71 5b db 36 9e d2 92 d8 73 dd 05 a0 32 a2 83 65 47 e7 c5 1d 0c fe 2d 8d 38 1d f1 b0 13
data 1 0b d3 27 66 f6 d3 2b fd ac 12 3d 02 90 2b 19 ea ba 05 68 5b d7 75 21 d6 a9 8b 18 2e d4 5e bc b5
data 1 b3 b1 72 bd 7e 9c 5c c3 ae 20 e0 40 b1 aa f6 6d 06 d5 e4 25 99 50 83 29 c8 1a 2d 0f d8 bb 34 34
data 1 b7 08 02 0a b6 50 7e 18 5c 87 4b db 88 69 b4 91 23 70 d0 2c 1a 63 f9 2b 17 39 ce ba 16 a8 27 8c
data 1 b3 ed 62 ed a1 0e 21 13 1b a3 4f ff 87 30 71 87 5c b6 e2 4d f2 ab 8f 8d d0 e6 04 45 90 41 4d 2c
data 1 f4 dd c4 37 55 40 d0 ed 04 29 6f 82 57 a3 15 1f 39 b0 d2 b7 c2 84 54 a3 01 e3 8a 11 83 b6 1a c2
data 1 58 d2 54 e0 73 cc e3 76 99 d3 10 a3 37 21 34 93 ff 77 2e cf a6 cb 64 02 6f 19 4e a5 67 84 a3 7b
data 1 28 2e b3 25 0f 4e 7a eb e6 45 fd 26 90 b1 05 74 cd a3 29 5f f9 f8 ad 6d 50 d7 cf 85 68 f0 29 c6
data 1 92 c9 24 06 4e 84 0c de 96 e9 1f 63 01 98 a2 a6 ef f7 d9 87 91 cf 8b 3d c7 26 41 2a bb be 80 39
data 1 11 e3 71 a5 b8 be 43 3a 1d d6 45 a4 59 b3 28 80 16 9a fb b0 51 b4 19 ff 2f 81 df e7 84 ff 0d a8
data 1 45 ce 58 0e 6e fa 5d fb 7d e4 e7 27 3a b0 8e dd 9e 97 e2 e5 31 90 2d 3f 85 6f 9e 3f f1 0c aa 15
data 1 d9 92 c7 db 6c 21 d7 65 3d 72 a2 97 29 3b 38 cb 35 82 8b cd 44 d3 55 51 65 5e 0c fb 67 a6 ee a7
data 1 aa 28 84 9c 91 75 db e5 2d e9 d5 2b 7c 85 ad f0 fb 9f 8d c5 70 37 a1 4c a7 94 81 1a 08 b5 cf 32
data 1 b1 03 9a 87 ec 9f c7 ad 2f f3 50 ab 62 05 9b d6 34 03 7f 6a 3d 8b 1f 97 c1 7c 95 0f c9 5a df c9
data 1 e0 35 a2 9c 30 7f e9 95 fc aa 2d c3 0c 08 ac 34 ca 7f ff aa e7 61 6b 03 5d 90 23 cd 07 cd 34 41
data 1 e9 ca 7e 0c 5a f3 58 b3 df 7a f9 d0 68 2f bf e6 d1 35 84 42 60 b3 41 ef cd c1 26 04 fe 97 4a 8b
data 1 e2 e2 d1 93 f1 f7 da 7a 79 ce 55 c5 9f e6 96 b4 0d 4d 0a bf fe 4e 5c cd ab 47 1b 0a ef 09 81 2f
data 1 99 74 5f 83 02 0a ed 08 ef 08 4c 01 9d cb 79 b4 86 31 ab 9d d6 dc 55 71 c2 ce 6f 10 86 36 15 54
data 1 f5 07 53 6b c4 ed 16 56 04 50 e0 66 4c 87 01 dd a7 93 49 28 ce 29 6c ab 96 f7 88 f2 78 07 4e ad
data 1 fd 36 96 c0 ee 26 d5 37 e6 99 13 28 58 b7 64 31 78 54 e1 86 9f 73 8d a1 4a a6 97 1d 3f 86 7d ef
data 1 2a df 1a e8 03 84 60 70 a7 99 bc a5 fb bb 45 dd 17 3e e6 ac 44 1e 9a cd c2 c2 68 cb 5a b4 d8 bc
data 1 78 1d 29 7d 19 72 81 dc 17 37 56 30 5a 68 71 16 cf ed c2 61 43 9f 52 10 0b 7e 48 ee cc 32 a1 d4
data 1 da 94 bd 2a 82 63 8e 57 97 fc 98 e8 c3 c5 29 18 d7 9e 00 07 be 82 aa 10 0f b7 52 03 45 ed f3 95
data 1 79 c7 64 d6 ac ed 0e b7 6b 4f 14 d2 8f 17 c1 77 f3 41 a9 37 47 b2 53 b3 68 f8 2f b7 84 2e 4c e4
ressu2 dd 3e 4b c9 f2 4a 4d 70 02 7f 49 f0 0f 59 e8 4f 6d fb 7f 87 1f 19 b5 a2 10 4c 03 af 10 b3 24 9d
ressu2 bf d2 6e d3 87 29 ab e5 7a 7e 44 db cd c7 bb 46 64 02 b8 ca dc 48 ed 20 ca c5 ed 2c c1 e2 8c 4d
ressu2 2c a5 f9 61 55 df a8 3c 91 f5 87 c4 b5 5f 91 95 88 5c dd a1 d8 5f b8 b1 41 5d a2 11 d8 d9 01 44
ressu2 ab 60 cd c8 81 0d 7e 0f 8d 82 87 27 03 d7 e5 48 ae 5f cf 02 8d 63 97 53 e5 11 77 c3 a3 e7 ae ed
ressu2 cf 46 c4 0c 93 4a a6 ce d8 41 5d 58 bc db 5d 79 96 c0 a4 d0 fb 66 d8 2c c6 66 45 3a 3a 6f 27 c1
ressu2 d6 de e3 d4 a7 ff e8 b0 c8 b3 82 61 98 0e 41 36 1b d8 11 e6 6b dd 62 68 89 39 73 c6 0c 61 1f 01
ressu2 63 d9 ed 53 da 40 2a 37 f3 41 d1 51 af 44 ec 0f 0a 8a fd 72 fe f6 c8 f5 d9 5c 12 d3 9f 0d 70 83
ressu2 0a c5 99 91 ff 96 04 47 90 46 f5 a6 87 8c f2 f1 ec c0 46 2c 20 56 5c e5 45 55 53 c6 17 a0 da a1
ressu2 51 07 76 cb 80 7b 70 6f 72 57 06 f2 93 63 5e e1 8c fc af c4 6f 4b 10 14 12 dc 22 91 07 db c2 ac
ressu2 4d 95 b8 72 fd b8 f5 48 91 fc e2 08 20 37 e0 52 ce 29 1b 11 2b cd 21 24 76 82 aa 68 ff 8e b0 e2
ressu2 61 1d 34 8c 95 40 0d df a9 5f 16 97 56 f5 89 e6 e0 0c 19 ef 28 af ae f1 79 15 6d c0 e1 ab c0 f9
ressu2 3f ba 67 8b 6f d2 6c e8 89 39 92 be a1 25 90 9c 93 c8 0b 00 2b 52 d1 4b e1 10 54 a0 7c a9 c3 12
ressu2 e7 3f 3a 7e c9 4c 9b 29 c6 e1 96 64 d7 0c 0e a9 81 c9 65 88 04 b8 4c b3 74 28 88 90 0c 58 86 17
ressu2 9c 3a 43 02 6d 91 41 e9 b9 44 e8 cd cc 56 3c 36 f4 68 19 7a e7 ed ac 26 32 1b 2b ee 31 d6 6b f3
ressu2 89 1d e4 81 72 a5 d0 4f 54 c6 92 73 74 b6 1e ce 92 83 cc ec 3a aa 24 97 ff 83 73 d3 ac f6 d4 69
ressu2 e8 9c 1b a3 6e 6d 04 d8 5e 3d 17 19 b1 7c 97 31 10 1f 5d dc 6b f2 59 85 e6 ff 70 72 60 e5 9b 18
ressu2 55 b3 7e c2 58 f4 23 4b f9 d2 39 0d e3 c5 f0 66 5e 90 fd c8 1c fd f2 19 01 48 5e 40 10 f0 83 7f
ressu2 ac df 43 00 f5 1c 8e 07 4a cd a2 43 68 b5 a0 f8 60 74 bf ef b6 e6 dc dd d5 8c 7b cf 26 3c 82 03
ressu2 cb ae 1e fe 56 7b d2 4d 0f d9 ea 61 1f 9a 76 d9 98 ef 27 4e 13 95 c8 bc 2d ba df b2 54 1b 47 fc
ressu2 85 15 a4 05 96 93 26 06 45 99 e6 36 5b a7 dc fe 43 95 a1 77 df 6b 64 ca 26 4c d9 34 4b f0 6c ab
ressu2 e0 13 31 e7 3c 84 75 bc ce 85 71 7b 54 e1 61 eb 02 92 c7 4b 63 46 26 f4 4c 01 6c 03 50 72 dd 55
ressu2 33 d2 f5 0a a9 a9 cb 2d a0 0d 25 6b 60 56 93 cb 5a 98 e9 52 97 48 da fd 04 6a 8a 6e 0e 7d ba 39
ressu2 46 bb 93 13 1e c8 e6 04 81 65 4a 6a f8 1d e4 57 ad a9 28 31 7f 2d 60 25 2e 5b 80 8d d3 85 ba 18
ressu2 5c 12 b6 80 77 05 47 1d 35 4d 1a 69 7a bb f9 60 d3 e6 c2 ff 53 f6 bc 1c 49 be cc fc 39 20 c7 8e
ressu2 92 e8 02 46 71 ff 6a 1f 91 95 6f bd 86 0e bd 14 03 81 af 54 d9 3c 7d ec 39 da c5 29 b5 28 ec e2
ressu2 5a 05 98 27 1d 4f ca 21 74 4e 58 94 d5 57 db 8a 8c c4 37 2c f4 91 ab e9 b1 c5 ba ac 82 9d c4 33
ressu2 19 50 ee 9a 9b 4d 17 fe 73 de 9c 28 d1 c4 7f c2 4d d0 14 54 57 17 dc d9 83 00 77 47 b3 8d 3e f0
ressu2 4a f8 f0 e3 2e bb 6d b2 b7 11 30 5d bc d5 38 d1 ae e5 1a 42 99 fc 25 2a 37 11 5d d3 72 35 cd 36
ressu2 82 cc f7 ae ee 69 41 df f4 18 95 75 f9 e7 c0 d8 8f 76 2e dc 41 ee a6 33 cc be eb 57 4f 05 a3 d1
ressu2 d9 74 a7 5a 46 00 2c 5e d9 2b 03 25 af 8d 22 bf 06 9d ed 50 cd 59 b9 08 b3 0c 5b 82 76 5a 29 81
ressu2 ad bb 46 e2 21 2d 37 88 29 f8 53 ab 99 ff cc 75 25 41 ec bb 88 38 73 48 4e d5 33 9d e5 f2 5d 85
ressu2 5f ea a9 cb 8b 02 69 85 2a a1 11 68 fa bc 7d c0 82 a7 05 e6 1e 74 2a 6a ac e0 65 80 6b 55 96 a0
ressu2 20 38 b0 dd 2b dd 2c 6c 79 7f 79 96 48 9e 66 44 26 55 6a c6 3a 94 a1 14 49 e0 11 af 3a df 33 08
ressu2 66 6a 91 95 64 28 8d 4e fd 96 6a 8a f1 2f 8f c4 15 58 b7 94 25 f9 13 4b fa 6a ef f7 f8 bd 43 ca
ressu2 08 64 ff 5c 45 2f 7d 44 23 29 d6 93 b1 d6 ac b9 f1 c3 e9 44 8d a1 23 2e d1 6e 89 be 03 9c 9e eb
ressu2 41 85 60 8d 22 41 9f 88 78 e9 e3 31 80 df aa d5 27 73 0f 45 86 b1 77 66 5f e1 23 68 1a 8a c0 a3
ressu2 fb 03 72 d9 8e a8 e3 80 bf 90 e2 bf 3a d1 cc b9 29 e6 6c 99 7f e3 0b 15 98 97 ed 30 c0 07 23 02
ressu2 29 66 ab 7b 44 58 90 b2 b6 9d 10 4e aa 80 6c 78 d8 d0 ee 54 09 f7 a9 00 05 99 ed 4c 9f 67 8d 97
ressu2 e6 34 47 d5 6a a5 42 b0 3d 17 4b 08 1f 9b 37 f8 08 e3 81 a6 0c 03 5f ef 0b 57 a2 d6 54 50 bc f7
ressu2 7b f9 8c 8f 99 60 ba 5f 7a 6b eb 61 84 1b 51 e0 f4 11 92 0e 9e a8 20 20 34 6b 76 d3 1e 68 ef 3a
ressu2 b4 22 e0 7b 3d 1e f7 fe 25 3e 59 95 ec 45 7f dc 9d b4 b4 8c 5f 3f 04 90 a1 b8 27 73 2f 2f 5f 00
ressu2 54 48 b2 f6 d7 2b fe 88 6b 5a 74 f3 79 8e 04 81 0f 29 7a 5d 22 58 cd a9 8e 10 7c 98 46 68 cd 4e
ressu2 22 84 cb 1f 8f bf 91 6c 1d 03 b6 d0 0e 2d f6 3c 94 55 99 21 a5 86 4d aa cf dd a9 f0 8f f6 3d 75
ressu2 92 2c 7b 55 2c 8b 68 c3 dd 59 66 99 7f 6f d2 7b d5 76 62 38 bf 10 b7 77 26 9c 60 73 82 d2 7d 50
ressu2 03 9e 2a 9e 91 ce a3 33 9b 84 65 a0 7b 4b 12 0e 84 7d 7e 81 c0 31 c5 2e b6 7e a1 9e b4 6c 23 1f
ressu2 14 70 6e 1a d0 04 04 30 23 58 ec 2e c8 d9 a7 ec fe d8 e6 b8 d9 c2 60 12 d8 f1 24 3e 56 c2 72 83
ressu2 4e f4 b5 6d 76 6f ad 5b fc 21 0f 7f ed 0d ff 85 09 fc b7 69 68 25 c7 9b 76 42 49 ae e3 e6 2b f5
ressu2 d8 99 bd 72 c0 44 c7 29 c6 d4 b6 5d 55 b7 a3 58 05 26 26 9d 64 b3 7f ed 68 9e 8f c0 2d 0c 5a 9d
ressu2 6f c1 8f bb cd 57 2c ce e1 e7 fe 52 67 d3 f6 88 f3 e4 1d 7a 69 c0 21 4f 6a 15 5a 36 c9 41 d8 8a
ressu2 96 36 7e 8b 19 66 a3 55 fb d3 91 da ef de 82 06 2e 76 a6 65 b3 40 f9 80 75 03 17 2a 3d 27 ee 97
ressu2 fd b1 56 8f 79 5a 0a ad eb e6 68 8b de 77 7e 65 75 e5 02 61 a9 42 cb 88 8d 85 c0 f3 d7 f6 a0 2d
ressu2 51 ee 2a ee ed 1f 4c 1b 87 1b 86 58 66 7b a9 7a 42 9f ca f2 b5 e4 9f 6b 10 ce 7a 10 6e 7a 2d 8a
ressu2 03 04 ad 4b 99 89 c1 15 6e ab ee cb c6 50 7e 71 a1 c3 35 2a a9 19 4f 7d b6 6e 83 db 81 3d f3 90
ressu2 da e5 4f c4 7a ce 99 4e 4f e4 14 46 1c ed f9 54 88 0e 99 eb 3b 93 34 0b a6 5b 39 26 17 79 f3 4d
ressu2 6a 16 16 7e 39 00 b2 8d eb dc 32 9a 91 a3 6e 42 f5 14 c2 46 ec 8d 0b f5 d2 2f e7 c5 9a a8 a5 54
ressu2 b2 5c 40 5c 62 87 84 59 2c 9f 70 62 91 c2 6b 95 0f 81 27 10 24 97 69 75 a6 4e 36 c3 a4 03 e2 53
ressu2 aa 7b 37 08 9d af d6 71 17 e4 82 2d 6b b4 3b d3 1d 94 00 d4 c3 6f e0 ec b3 87 ae e3 a3 11 94 58
ressu2 56 f3 70 30 90 60 dd 4a bb 52 bd 08 3a 20 92 a8 80 6d f0 b8 58 8e 55 5c 5a 0f b1 2a f9 0f ad f9
ressu2 a7 b2 ad 91 b5 63 aa d9 23 8c 58 fd 25 59 09 e7 4c 0d 01 63 57 96 ed fa e9 e3 5e 41 41 b0 18 31
ressu2 5e 04 9e 6d 82 d0 38 98 4e 19 e3 aa 41 b4 83 1d a7 f0 91 6f 90 54 44 de 85 7d 5e 52 45 88 1e fa
ressu2 d5 0d 84 18 b1 84 b6 e6 b5 38 10 30 48 21 8f 7a 37 86 61 97 c8 c7 80 c8 61 2b 64 63 74 4c 00 4a
ressu2 db 3b c7 39 f2 e6 e7 76 05 ea 0d b4 9f 1e a3 17 02 22 53 0e 65 6a 1e e6 a3 02 10 04 b6 f4 5e b1
ressu2 3b 48 96 d6 9f 59 b9 2c 5b d1 23 d6 c5 9d 0c b8 35 b9 56 fa 5b c0 bd bf 64 f4 5a 27 6b ed 04 79
ressu2 95 67 5f 0a db 3f 9d 9a f3 a3 2b a1 7c 1f 40 69 d6 9a 4f 0a 23 3a a7 be c2 12 af ed 4a 50 fa 22
data 1 dd 3e 4b c9 f2 4a 4d 70 02 7f 49 f0 0f 59 e8 4f 6d fb 7f 87 1f 19 b5 a2 10 4c 03 af 10 b3 24 9d
first key dd 3e 4b c9 f2 4a 4d 70 02 7f 49 f0 0f 59 e8 4f 6d fb 7f 87 1f 19 b5 a2 10 4c 03 af 10 b3 24 9d
data 1 bf d2 6e d3 87 29 ab e5 7a 7e 44 db cd c7 bb 46 64 02 b8 ca dc 48 ed 20 ca c5 ed 2c c1 e2 8c 4d
topup bf d2 6e d3 87 29 ab e5 7a 7e 44 db cd c7 bb 46 64 02 b8 ca dc 48 ed 20 ca c5 ed 2c c1 e2 8c 4d
next data 0e 00 b3 66 df 8a cb e6 dc e5 4e 61 15 c6 af 80 f8 1b 41 74 3d da eb 2a a2 7f 70 fd a3 7e 5b 7e
next data d8 f8 a9 3d 4c ed 43 10 23 13 2a 7f f1 da e5 6d ac a8 f4 fc 1a b9 fd d7 8f 74 8d 71 98 70 59 dc
next data c4 4b 0e b1 5a bb 25 06 67 90 b3 bb d7 5f 93 f3 8a 4d ac cc 29 d5 35 20 19 38 ef 4d 97 9d 29 8e
next data 76 6e 9d cb ea 7a e5 d7 a8 0b ef 86 1a 53 10 23 3e 5c c6 12 88 c0 10 c2 0e 89 55 17 49 52 b0 78
next data 86 c5 cb 97 6f e5 10 0d 62 06 8f 77 53 67 f0 b5 1e 01 55 81 67 3e 8c ea 1f 82 69 29 40 af fa a3
next data 46 f4 89 43 03 02 f1 1f b9 d2 c0 5e cb e5 6b 87 f9 95 f8 46 6a 67 d3 9b 36 7f 42 f0 91 60 d6 39
next data 66 7d 9a 1d 11 ab 14 89 38 97 c0 4d f6 f8 26 ed 40 0e b0 5b b7 5b 33 91 d3 73 14 bf de 79 33 f1
next data fc 4b 11 04 cc 92 4f 18 52 2f 20 89 70 b7 36 91 c4 e0 8c 16 7c 77 18 a1 7b 01 b9 4a f1 b3 6e 3f
next data 34 fc 48 07 7a 92 42 3b 36 c1 9f 9b 8f 48 c1 35 3e 78 fc d1 74 ea 53 78 2b 91 ee d5 5f 48 79 90
next data 56 b6 7a 83 a9 d8 b5 4c 8d 0c 8b 5a 6b 0e 25 be 81 4f ed 92 e1 21 03 55 e5 5a 7a 87 f5 91 31 30
next data 18 79 98 41 a6 a4 11 e7 1b 84 3e f7 9c 40 89 12 be e6 b9 69 ee 31 ff 59 65 68 57 aa 96 c1 21 4e
next data 48 64 52 ba 6d fd 5e 3f 47 9f 3c ee c5 4a 68 b6 b0 d6 ab dd 14 30 4b ca 8d fc 75 64 d2 c8 a7 ae
next data 4e 23 50 30 ab 86 19 b6 73 b6 36 4f 75 0f 3c 93 b7 e8 35 53 04 3b 64 a2 e5 b4 a7 7d dc 31 d7 f8
next data f3 19 00 60 08 67 f6 11 5f 4c 16 ee 88 30 82 07 39 d3 e6 3b 77 63 8a e6 92 91 3d ec 5d 5b 70 1c
next data cc fa 28 67 be ec 0d 49 39 f3 37 a3 65 c3 af 0a 40 05 94 b9 28 cc 4c 65 26 85 c2 1b 8a 40 f5 e6
next data 47 ea 4b 35 d4 04 ed 09 93 c7 07 8e 98 f5 0a 73 1e 0e f9 08 67 7e bd 18 ab 2a e6 88 09 c2 1d d8
next data 62 06 dd 89 52 78 c2 6d f2 18 8d a6 f3 1f 0d bf 8b e3 46 be 33 11 0c c4 b3 0e 58 e6 e8 a3 08 15
next data f2 39 f9 fe 4f e3 d1 54 f7 57 82 a7 61 5b 99 1b 10 1b 18 12 86 a0 6a e3 27 55 5b 13 cb d0 b2 86
next data be 63 c7 0b 02 a9 f7 e1 3b db 99 16 13 dd 8c c2 e8 c9 9f b5 36 e8 14 90 c3 93 73 1a f3 7a 1e 41
next data 86 93 d5 04 cf b7 b7 2a 1b 0e c7 5f 93 6e 01 bf e7 b5 7d e6 4a 4f 38 07 55 8a 6a 50 98 dd 97 0f
next data a9 e0 51 2a 86 cf 82 49 b1 31 66 52 ab 77 20 5f ad d4 01 93 fb f3 37 5c a1 d4 1d ea 1e 9b 22 ba
next data 9a f7 97 c3 7e aa 17 4e 2e e6 8f 28 63 11 53 9a 31 2d 74 2d 55 b3 de 8c 58 47 27 cc f8 92 27 3a
next data 71 bd 66 d3 5e 13 9b 62 f9 5d b7 cc 77 fb 9a 78 0b 2b 43 7a 76 58 59 d6 2e fa 27 af 27 ba 13 b8
next data 89 9d 79 70 80 ea 18 ea e9 f1 71 5c 5c 93 50 cd 83 c9 0b e4 0d c7 5b 42 1a 76 e1 8f fb 61 3e aa
next data 36 1a a6 ae 5c bb 1b a8 dc db 9f 38 5d 7c 2f 52 d1 a0 bd 8c 55 0a 40 7c 6d 07 5c 7b 96 59 53 c8
next data f4 4d 2b b1 4a df 9d 48 0a 6e fc 79 c0 2a 2c 01 ad 8c e9 39 ef b2 8b 6e bb aa 8f 2b 57 3a f3 ea
next data e3 f2 19 f7 e0 c2 f9 91 0c 7a 8a f3 7b 21 c9 d5 56 9f 7c a9 d0 8d 3c 5e bb b5 1f 6d 05 1f c7 5f
next data 58 fd 25 fa 6a dc 77 6d 81 c9 a1 8f 1c dc 73 05 c4 29 46 54 61 35 ff 77 ee d8 cc 0d 96 c3 18 2d
next data fb 9d a2 59 22 83 26 76 60 f8 71 4d 9a 81 de 0a b7 55 c8 0e 2e ff 4f c3 62 ce e1 c1 49 8a 7c 63
next data 08 a5 c0 18 d6 56 fb df bb e9 18 40 65 7d 72 f6 ad 25 eb 59 d0 75 7b e9 5d 24 b1 6d 8e bf 56 86
next data 8c 9d 4a f3 d9 8b 8b b1 cf ec a8 fc 50 db b4 57 5c fa eb ef 16 e0 f3 b4 82 11 85 fd 76 cf 9f ca
next data 34 8d 56 0b 19 93 87 95 c0 f4 96 0d 2a be 57 f1 4f 66 45 6e a4 2a 59 5e 98 eb 91 57 99 1b 62 6d
next data 1a fc 80 ad 6d 3d 48 f4 8d 48 05 6f 0f 14 76 18 ca cc d2 fb 36 0b 60 ed 2d e2 9e 39 80 0b 6e 64
next data cd e2 5c 1b 76 13 ee ab 99 8e 7f d6 ee 14 3e b8 75 3e e9 fa 21 97 e9 71 cc e5 ac 04 c0 65 bb be
next data 30 60 63 b5 c7 a3 ad a9 31 44 fc a5 e6 89 32 4b 6e e2 30 04 81 b6 f7 bf e2 86 26 0b 12 0b ec a3
next data 76 6d 47 e6 0d 1e 4d 4d 48 db ec f7 db d8 59 3a b5 97 68 01 ce d0 dd 7c f1 ce 80 80 8a da ee 2e
next data 4c c1 46 c9 d2 74 dc 69 c6 46 1a 46 66 ce b8 d7 6f fe 1e 09 fc e6 b9 6e 76 76 17 6e 06 de 62 cc
next data 87 58 33 e4 b6 58 c2 0c 7b cd 7e ff 5e 6a 0e 99 c8 86 90 3a 7c 45 a3 78 88 36 77 dd 53 5c be d3
next data 73 a1 56 43 22 17 ee 28 51 8b 5b 5e 0c 66 77 ac 50 8d f3 aa 9f a5 45 bb 34 a6 58 e7 a3 77 e1 b9
next data bf ac 10 a6 36 33 62 f8 d4 b3 7e 31 ea 44 dd e5 86 86 65 60 15 c6 00 a8 e8 01 6e 3a f5 78 5a ba
next data 98 a4 8a 3c d4 c6 f3 54 b9 62 51 57 46 14 88 52 8d 6b d4 35 de b6 9d ab 87 ea 58 b1 da 98 12 3b
next data d4 7a 3e d0 82 b2 18 d1 8f e5 6c f4 6b b4 2d 35 0e 9c 92 1f 6e 63 d4 34 9a d9 43 2d b9 37 51 6e
next data 7b 75 dd eb 35 0b ee df cc e3 39 9b 3c f6 a1 4e 1a 3d f2 96 25 00 6d 6c 06 84 c6 36 1b c1 cf db
next data 5b dd 8b 8d 8b 6d 26 60 a6 66 51 09 07 25 ec b0 86 4d 39 95 b3 51 68 a2 52 38 06 83 6b 1a 3a e8
next data b8 ad 57 91 f6 89 06 e4 38 7b 2d 6a e1 a8 2d f4 4e f0 11 d4 13 3c d0 2e a5 4e 77 93 75 2b 55 a4
next data 67 de ab ba c2 03 f7 18 71 87 84 93 25 8d 5c 7c bb ab c8 09 b9 96 a6 83 b1 2e 41 fe 9c c1 36 cf
next data f5 1d 23 c9 6e b1 3b 2c ae 9a 06 54 fe 6e 09 0a 64 b1 5d 31 a7 cd ae b9 12 21 b7 5e 23 62 9d dc
next data 21 a2 a5 15 f0 e1 4b df b3 bc bf d8 cf a5 a7 dc d5 8a ce 71 d4 2c c9 96 0b 41 b6 25 8a 15 e2 09
next data fc 51 39 d9 31 da 1e 72 08 a8 87 dd 44 5c a1 32 b4 45 15 f1 bc c4 e5 7b 16 cc 8f 27 74 24 c7 73
next data e5 a6 e4 25 b8 05 08 50 83 69 f6 68 68 f5 d6 f6 f0 3b eb 03 d7 1e 30 b8 65 23 a0 7a 55 08 61 34
next data 88 cd e8 d1 9f 62 a8 a7 58 4b e9 c3 66 2a c4 4d d8 b3 55 b2 82 65 47 44 10 88 c3 34 bf d2 3e 78
next data c6 85 fd b0 9b 4e bb 8f 3d 8d 0e a5 84 e5 96 a7 37 5d 31 8a ac 4c e1 ff 7d a6 78 2b a8 88 25 e9
next data 4d 74 e2 2d d7 f3 b6 7b 24 12 82 41 4e 45 c3 f7 7a ec 33 08 a2 8d 1d 3b 28 4b 15 1e d1 6c 52 bb
next data 78 4b f8 81 ee 98 f2 b3 ae 4d 19 94 d7 92 50 5b e6 c5 5a d7 b7 9d 53 98 6c 78 4a 30 9f d9 a7 08
next data 62 23 4b a1 e8 d9 32 ab ed 05 cc e1 d6 86 a8 1f 4a 4c a4 85 a1 1d 00 54 55 b4 13 ed 5d 2c 85 86
next data 0f 05 db 68 d4 03 2d e7 f4 6d d8 c7 b8 97 7e 86 03 02 d6 f0 e8 7b 1a 4f 05 e7 d1 ea 88 8a b4 01
next data 3c bc b7 c0 35 f1 75 93 ed 75 ab 07 a0 7a d8 ff 83 66 5e b1 d9 9c 02 ca f8 0e c9 5d 4b f0 1a 66
next data 1a 78 25 af 19 5f 30 c8 31 72 15 79 88 27 e6 5d 21 7f f1 9d a2 14 31 f9 fb 90 94 06 5c 91 0f 6e
next data 7d 98 0d 95 0d c5 b5 86 d8 cd b1 dc 84 f8 98 d2 ce c1 3a c2 0e 44 df 3c 1d 69 84 92 20 bf 08 c8
next data a9 3d 51 36 c3 60 9a ca 4e ba b9 54 bd ef 78 32 84 19 60 6f ef 64 bb 14 07 04 83 93 47 87 0b c7
next data e4 af 63 69 15 23 34 24 14 24 6e d2 c3 c2 b7 42 d9 de ce e6 4d 3a 71 29 70 da b2 3f 46 64 1b 20
next data 97 91 51 17 5b ce 18 b3 2e b6 5d 24 11 60 4e 83 5e b2 93 87 78 03 7d 42 3c a8 0d bd fd be db 13
next data 44 71 52 ce 4b 17 00 6c d6 be 28 34 0e b5 a8 70 4e 3e a9 03 87 09 8d be 38 23 c3 b6 88 f7 e6 e1
next data 6d 8e 11 be a7 60 d2 34 76 12 23 1b 1a ac 49 e0 7f de d7 0f 81 10 9c 51 36 b7 44 69 ba dd fd 38
new key 51 f3 35 52 98 72 3f e7 1a 02 41 26 19 6e a4 64 90 89 f3 60 ca a6 c5 ec 5b ac b8 56 fd f8 02 c7
data 2 65 e5 1d a2 96 79 35 b4 35 ff 5f 21 83 90 1b 86 72 02 7e c2 23 00 d2 de 54 97 79 f7 73 34 df bb
data 2 e4 87 a2 8b 41 ba c8 83 75 61 aa 88 76 90 c3 c9 57 7d 6b 50 a6 e5 e7 a4 7f 20 42 b4 75 53 11 2b
data 2 b9 c1 c7 58 a3 c9 7d 3f cc ff 05 37 b7 d6 f9 ef 31 3a a5 d9 db 83 ff e6 1e fb 6d dd 54 1e 2d 13
data 2 57 39 8b 5f 5f 26 fd 10 b0 92 f9 d1 1c 1f f9 3b 8b 6a 9d ef bf 5e 22 23 b9 16 b9 dc c6 a1 db b0
data 2 23 d0 0c a1 af 2f fa a2 90 0f e7 c2 98 2e 4b e0 f1 3c db 91 ab 90 ef 6b c1 fe 5c 89 4b f9 2f 9c
data 2 5a ab 30 2d da bb 88 96 ab 02 d4 f6 0c 23 2e 84 03 1c eb 65 49 35 b0 c0 0f 71 2e 9d 35 dd 50 44
data 2 92 09 eb 7b 81 44 44 a7 ea 2a 5d ae b1 e6 60 5f b5 59 c9 8c 26 4f 63 94 28 0c c5 43 2f 73 6c 98
data 2 ee ec 10 5e a6 fb f4 df c3 bc 6c b4 56 ff aa 6a 72 36 83 37 6f 04 e1 0e 97 47 79 17 07 3f e6 ce
data 2 4e bf 73 b5 d1 03 bf b0 4d 60 6b 5b aa 7d 28 36 f9 97 4e 5f c6 a4 57 bc 87 01 16 cd e8 b5 22 df
data 2 ae 1b 23 f6 07 0e 7b f9 bc 69 02 76 22 e0 96 f1 fc c0 9a 5f 93 2c 21 6a d5 cf d5 e2 8b fd 79 ca
data 2 8b 19 ce e4 91 b2 46 3d 0e 3c bc f7 fb 19 51 0c 9e df ca 23 a8 53 31 37 90 2e 39 82 ea ce 2d a6
data 2 87 43 25 e3 6a ef ed 60 7a 11 9d 2b 0c 9f 9e 72 16 2e 04 e6 a0 dc fc f3 89 82 a3 db f2 6b b3 63
data 2 b1 66 a7 f9 8b e9 3e d7 b5 84 66 af 8d b5 bb 4f 97 a5 eb 0f cc 5e a7 3b 2b 8b 3d 50 f7 b6 5e 22
data 2 86 61 6d c5 dc f5 f0 8d 28 d9 6c fb 7d 5c cb 67 ee c1 8d de 8d bb 23 47 cc 04 9e 2f 3a 93 05 a0
data 2 ec 7d 34 8a 9d 73 d2 85 b3 23 8a 81 44 0a dd 46 06 3f 03 53 26 5a 2a f5 a6 fa f3 59 dd 27 9e fc
data 2 1b 15 04 fd 9c 13 a1 dd b8 2b 8c cf 8f 23 b8 9d 7c b6 45 34 93 f1 b0 05 eb 27 8e 84 c5 3d 97 f2
data 2 d1 21 03 44 ee e1 32 12 8b 5c db 0c 2e ba 64 a6 18 ac 4e 53 9f f6 60 df 68 6e 6e 3e 74 23 2b 36
data 2 95 83 78 c6 a8 9a ac 16 69 c5 f2 77 c2 df 08 c9 44 00 bd b4 a0 d1 71 be ce bf c2 58 a2 f4 47 d4
data 2 54 09 e6 17 c9 cd 1a 62 bb 89 81 1b b1 5b d6 57 6d 56 b3 75 d9 99 a7 37 5d 3e 0a 29 d6 41 13 fd
data 2 16 13 c9 f0 20 dd 1e dc 32 0e 52 f8 93 87 07 55 2c 19 a2 ee 9b f7 e8 1c a5 02 8d 25 5e c5 b2 5e
data 2 ca d1 ff c6 4c 41 7f 20 ef 3a 3c 67 0e ff 9e a1 67 2d 2d 51 82 f0 39 19 ff 42 d8 db d7 e0 af 3f
data 2 f4 f1 72 79 45 7e b5 e1 ba 19 4f 7f c9 88 7a 06 24 35 93 24 ea 13 80 76 5f 42 11 1b 49 c5 be c2
data 2 ee b4 80 9e 27 ac 90 ca b7 c3 b2 99 b1 6a eb c8 ee 16 d7 79 f2 6d a3 fd 5a 3b 2b e5 58 82 af 1e
data 2 43 3d e4 c6 2b ab 9c 16 3f 91 e2 57 38 eb ff 3a 20 59 f3 eb cb 0c 30 41 f2 53 f9 bf c0 12 58 f7
data 2 f9 4b a7 02 a0 10 0a a8 01 80 ea 61 0b e5 3f 96 91 29 47 46 9a 55 2a 91 de 53 63 53 e7 c5 18 54
data 2 50 97 db d8 15 d3 07 30 48 d3 ba 32 1e a9 f7 7b 32 dc 38 d5 44 76 e6 8c 49 15 d6 41 a9 d5 21 db
data 2 97 87 2b 02 16 be 42 65 d9 d7 8e 17 51 e8 21 e7 e7 2e b3 3d 3b 15 9b 14 79 65 9c 86 9a 71 fd dc
data 2 de a5 11 37 13 47 73 e8 6f e6 63 de 35 26 cb 4e 84 30 5a 5b 64 b0 45 73 a5 5c fc a3 b8 07 17 3a
data 2 7d 55 b6 d7 b3 f4 d8 4d 71 c8 2c 8b e2 3f 5b fe 7e 80 11 a2 e9 89 44 e1 46 13 cc 9f 80 9d f4 ce
data 2 dc 50 e0 65 ee b7 4c 59 ec a4 fc 3f 5a 11 30 27 bf f5 2f 2a db 9d ff 01 e4 c2 44 02 63 50 8a 8d
data 2 70 d3 14 af d7 01 32 0f cb 4f aa 94 b2 33 fc ec 58 ca 42 c9 a7 f6 87 29 a4 a9 08 41 10 ab 17 e9
data 2 4e e7 31 ab da f5 36 02 07 63 e2 a2 eb b7 e5 f2 45 6e 65 73 0f 6a 67 fb 02 30 5e c0 a8 e5 66 1e
data 2 ec ac 78 89 ba fa e7 03 01 9f 27 56 49 91 f5 c1 58 7a b1 b2 32 20 05 22 8b 2b 2e 81 d5 67 48 53
data 2 f2 7a e6 cd 96 3a 3a 15 f1 63 3d 77 6d a6 99 63 91 cd 5d d4 f7 aa 7a bd f9 04 bd d7 22 ef 7d dc
data 2 0b e5 c5 51 01 27 ea fe 4d d9 53 ca 9f 17 ac a8 8c cc 8e 95 a1 18 02 55 58 1d 83 d2 1b 04 7b a4
data 2 2a 01 32 0c b7 58 c0 ce ab 76 d3 c6 c0 6a dd 9f 6e 34 33 80 3e 60 de d0 1c 94 58 08 5f f6 f4 ab
data 2 26 4a 5e 4c 8a 23 50 a9 0e 47 c9 cc 82 b7 43 c1 53 58 06 ce 07 b0 67 3d c9 52 63 d2 72 65 80 8c
data 2 ef a7 36 16 a7 32 de e5 9c 57 87 c6 05 ae e4 b8 41 bc 43 23 ad 82 79 6e ce e3 09 38 ee 10 4e 37
data 2 24 58 74 f7 b7 b4 fe be 5a 15 e3 88 77 15 49 1d d0 97 22 31 ae 2e c0 97 39 c5 30 98 7b 0f 7a 0f
data 2 1f 6d 9b 20 ea bb e9 f6 af 15 ef 33 72 aa b0 f1 f4 28 e3 0e 86 17 70 9c da 3d 2b 38 9a e2 0b 63
data 2 f8 1f 13 4d 8f 1d c5 ca 6b f0 89 24 9b 11 28 60 2f e8 b1 72 39 73 80 a7 79 c7 d5 89 c7 69 a2 28
data 2 df a9 19 b6 74 61 33 2c 23 f7 51 f6 fb 9f 34 df b4 99 fa 44 b9 16 f5 e2 33 52 5b 03 6d 69 ed db
data 2 c8 c4 af 56 4b 97 b2 1c 62 c3 d9 db 8d 5c 57 23 1c e8 16 b3 bc 50 ee 45 ce 9e eb 39 c3 7a fb ef
data 2 ec d5 89 87 3d 3d 58 78 fa e1 1a d2 8f 4c 58 21 a5 3d e9 b9 a9 32 91 89 45 01 c8 39 7d b2 1d 64
data 2 0b 40 35 7c 57 87 27 f7 23 d8 62 95 66 98 5c 73 12 46 f3 99 e1 97 5f a3 75 a8 73 d6 e5 6a 18 88
data 2 93 03 6f 8d 97 43 27 f5 75 ae eb 11 72 2e 49 63 82 1b 1a be 7b 12 f2 20 b0 cd cb ef 1f 77 2c 0d
data 2 ad cf 77 29 1d 7d d8 5a 37 49 16 f7 c9 4f 3d 99 9b c6 73 fe 01 06 ca bb 7d 38 f9 fb 44 e6 3e a7
data 2 09 8c 16 30 ff af 31 34 55 f9 42 fe 5f 14 a2 a8 18 29 e7 2e 2d d4 64 fb 5b 96 79 a0 e2 e5 cb cf
data 2 6e 98 1d df 7f 5e 12 ac 9e 41 98 be 45 c4 03 94 5b b2 cc 76 2d 0b 6e 46 d1 ea ce 0d cf 9a 47 4a
data 2 f4 45 95 80 00 bb 4b 6a 9e bf b3 cc 31 46 fe 76 e6 a1 10 b3 86 aa 29 47 4a a2 7f 9d d1 f7 6c 9c
data 2 cd 03 b0 df f1 98 f5 5c 25 af 0e e4 5c 9a 4a 90 46 24 b7 57 b3 f5 6a 7b 95 e7 5d 0b 4e de 94 6d
data 2 1f 17 3a 6b f7 6f 6c ea 00 ff ac 32 ad de ae 6c 02 df ba 47 e8 9f b4 ae 18 f8 74 d0 cf 2e cb 4e
data 2 e7 5c 66 b1 46 86 6d 9e 09 fb 57 6a 32 c0 6e 07 81 73 be cd d2 ba bc 77 8f df 94 04 d9 d9 9d 89
data 2 c9 48 62 06 02 07 35 1e 81 be 49 3f b5 97 cb 8d d2 c6 25 bd 8a 16 4c 0f ad 04 df 3f 56 83 78 c1
data 2 82 16 e9 3d d8 a6 db 3e 11 af e1 22 da 8e 04 2b 80 33 5b 2f 46 7c 6b 57 08 24 30 20 5a e1 b1 c7
data 2 e6 cf a5 64 8e f0 75 54 2b 17 21 17 d0 b8 c1 60 d2 37 52 b2 88 c8 5b a0 c8 26 f7 ee 76 1d fe 8a
data 2 de 5e 66 53 c4 06 af e9 94 bb fe c2 3f 9c 4e 4b 8e 2b 54 0e 27 d2 5e 07 53 49 d2 57 a4 f9 9b 49
data 2 83 0c 7a 2c 1b 55 dd c0 de 7a 59 78 15 ec 9f e9 a7 4e 5a 00 74 c8 64 88 39 5e fb 16 da a7 1a 3a
data 2 88 9f 5e fe c9 28 a3 d0 dc 9d 51 ba c8 7f 99 0f 69 52 73 ea c0 6d b3 97 8b 9e 0c 60 58 b8 46 65
data 2 54 0b c7 f6 2d 46 4f fd a8 23 aa 7c e5 58 1c 03 fc 4d 81 e9 70 17 36 b5 4d a2 14 8e 78 01 76 28
data 2 ce 70 79 81 16 a7 54 54 b3 bd d2 77 38 79 f2 9f ce e0 28 4a 09 24 eb e4 b2 18 da f4 1c d0 c3 9c
data 2 ef 8c 78 6a 42 bc 99 6f 39 81 0b 14 4b 08 3f 95 91 5f 51 e6 3b 9c 2f 52 37 d6 45 53 31 8c 7a c7
data 2 9e e5 ef e4 c9 74 8e 3b 41 42 b0 dc cd 70 81 68 99 a0 a9 04 39 8b 27 ae 37 94 91 b5 cd 1a 15 74
data 2 14 49 75 68 0b 8d dc 83 1d 5d 37 c9 95 bb 88 97 8c 9f 7e 38 c6 a2 cf e2 5e 4f 6b de 3e f3 b1 dc
data 3 65 e5 1d a2 96 79 35 b4 35 ff 5f 21 83 90 1b 86 72 02 7e c2 23 00 d2 de 54 97 79 f7 73 34 df bb
data 3 e4 87 a2 8b 41 ba c8 83 75 61 aa 88 76 90 c3 c9 57 7d 6b 50 a6 e5 e7 a4 7f 20 42 b4 75 53 11 2b
data 3 b9 c1 c7 58 a3 c9 7d 3f cc ff 05 37 b7 d6 f9 ef 31 3a a5 d9 db 83 ff e6 1e fb 6d dd 54 1e 2d 13
data 3 57 39 8b 5f 5f 26 fd 10 b0 92 f9 d1 1c 1f f9 3b 8b 6a 9d ef bf 5e 22 23 b9 16 b9 dc c6 a1 db b0
data 3 23 d0 0c a1 af 2f fa a2 90 0f e7 c2 98 2e 4b e0 f1 3c db 91 ab 90 ef 6b c1 fe 5c 89 4b f9 2f 9c
data 3 5a ab 30 2d da bb 88 96 ab 02 d4 f6 0c 23 2e 84 03 1c eb 65 49 35 b0 c0 0f 71 2e 9d 35 dd 50 44
data 3 92 09 eb 7b 81 44 44 a7 ea 2a 5d ae b1 e6 60 5f b5 59 c9 8c 26 4f 63 94 28 0c c5 43 2f 73 6c 98
data 3 ee ec 10 5e a6 fb f4 df c3 bc 6c b4 56 ff aa 6a 72 36 83 37 6f 04 e1 0e 97 47 79 17 07 3f e6 ce
data 3 4e bf 73 b5 d1 03 bf b0 4d 60 6b 5b aa 7d 28 36 f9 97 4e 5f c6 a4 57 bc 87 01 16 cd e8 b5 22 df
data 3 ae 1b 23 f6 07 0e 7b f9 bc 69 02 76 22 e0 96 f1 fc c0 9a 5f 93 2c 21 6a d5 cf d5 e2 8b fd 79 ca
data 3 8b 19 ce e4 91 b2 46 3d 0e 3c bc f7 fb 19 51 0c 9e df ca 23 a8 53 31 37 90 2e 39 82 ea ce 2d a6
data 3 87 43 25 e3 6a ef ed 60 7a 11 9d 2b 0c 9f 9e 72 16 2e 04 e6 a0 dc fc f3 89 82 a3 db f2 6b b3 63
data 3 b1 66 a7 f9 8b e9 3e d7 b5 84 66 af 8d b5 bb 4f 97 a5 eb 0f cc 5e a7 3b 2b 8b 3d 50 f7 b6 5e 22
data 3 86 61 6d c5 dc f5 f0 8d 28 d9 6c fb 7d 5c cb 67 ee c1 8d de 8d bb 23 47 cc 04 9e 2f 3a 93 05 a0
data 3 ec 7d 34 8a 9d 73 d2 85 b3 23 8a 81 44 0a dd 46 06 3f 03 53 26 5a 2a f5 a6 fa f3 59 dd 27 9e fc
data 3 1b 15 04 fd 9c 13 a1 dd b8 2b 8c cf 8f 23 b8 9d 7c b6 45 34 93 f1 b0 05 eb 27 8e 84 c5 3d 97 f2
data 3 d1 21 03 44 ee e1 32 12 8b 5c db 0c 2e ba 64 a6 18 ac 4e 53 9f f6 60 df 68 6e 6e 3e 74 23 2b 36
data 3 95 83 78 c6 a8 9a ac 16 69 c5 f2 77 c2 df 08 c9 44 00 bd b4 a0 d1 71 be ce bf c2 58 a2 f4 47 d4
data 3 54 09 e6 17 c9 cd 1a 62 bb 89 81 1b b1 5b d6 57 6d 56 b3 75 d9 99 a7 37 5d 3e 0a 29 d6 41 13 fd
data 3 16 13 c9 f0 20 dd 1e dc 32 0e 52 f8 93 87 07 55 2c 19 a2 ee 9b f7 e8 1c a5 02 8d 25 5e c5 b2 5e
data 3 ca d1 ff c6 4c 41 7f 20 ef 3a 3c 67 0e ff 9e a1 67 2d 2d 51 82 f0 39 19 ff 42 d8 db d7 e0 af 3f
data 3 f4 f1 72 79 45 7e b5 e1 ba 19 4f 7f c9 88 7a 06 24 35 93 24 ea 13 80 76 5f 42 11 1b 49 c5 be c2
data 3 ee b4 80 9e 27 ac 90 ca b7 c3 b2 99 b1 6a eb c8 ee 16 d7 79 f2 6d a3 fd 5a 3b 2b e5 58 82 af 1e
data 3 43 3d e4 c6 2b ab 9c 16 3f 91 e2 57 38 eb ff 3a 20 59 f3 eb cb 0c 30 41 f2 53 f9 bf c0 12 58 f7
data 3 f9 4b a7 02 a0 10 0a a8 01 80 ea 61 0b e5 3f 96 91 29 47 46 9a 55 2a 91 de 53 63 53 e7 c5 18 54
data 3 50 97 db d8 15 d3 07 30 48 d3 ba 32 1e a9 f7 7b 32 dc 38 d5 44 76 e6 8c 49 15 d6 41 a9 d5 21 db
data 3 97 87 2b 02 16 be 42 65 d9 d7 8e 17 51 e8 21 e7 e7 2e b3 3d 3b 15 9b 14 79 65 9c 86 9a 71 fd dc
data 3 de a5 11 37 13 47 73 e8 6f e6 63 de 35 26 cb 4e 84 30 5a 5b 64 b0 45 73 a5 5c fc a3 b8 07 17 3a
data 3 7d 55 b6 d7 b3 f4 d8 4d 71 c8 2c 8b e2 3f 5b fe 7e 80 11 a2 e9 89 44 e1 46 13 cc 9f 80 9d f4 ce
data 3 dc 50 e0 65 ee b7 4c 59 ec a4 fc 3f 5a 11 30 27 bf f5 2f 2a db 9d ff 01 e4 c2 44 02 63 50 8a 8d
data 3 70 d3 14 af d7 01 32 0f cb 4f aa 94 b2 33 fc ec 58 ca 42 c9 a7 f6 87 29 a4 a9 08 41 10 ab 17 e9
data 3 4e e7 31 ab da f5 36 02 07 63 e2 a2 eb b7 e5 f2 45 6e 65 73 0f 6a 67 fb 02 30 5e c0 a8 e5 66 1e
data 3 ec ac 78 89 ba fa e7 03 01 9f 27 56 49 91 f5 c1 58 7a b1 b2 32 20 05 22 8b 2b 2e 81 d5 67 48 53
data 3 f2 7a e6 cd 96 3a 3a 15 f1 63 3d 77 6d a6 99 63 91 cd 5d d4 f7 aa 7a bd f9 04 bd d7 22 ef 7d dc
data 3 0b e5 c5 51 01 27 ea fe 4d d9 53 ca 9f 17 ac a8 8c cc 8e 95 a1 18 02 55 58 1d 83 d2 1b 04 7b a4
data 3 2a 01 32 0c b7 58 c0 ce ab 76 d3 c6 c0 6a dd 9f 6e 34 33 80 3e 60 de d0 1c 94 58 08 5f f6 f4 ab
data 3 26 4a 5e 4c 8a 23 50 a9 0e 47 c9 cc 82 b7 43 c1 53 58 06 ce 07 b0 67 3d c9 52 63 d2 72 65 80 8c
data 3 ef a7 36 16 a7 32 de e5 9c 57 87 c6 05 ae e4 b8 41 bc 43 23 ad 82 79 6e ce e3 09 38 ee 10 4e 37
data 3 24 58 74 f7 b7 b4 fe be 5a 15 e3 88 77 15 49 1d d0 97 22 31 ae 2e c0 97 39 c5 30 98 7b 0f 7a 0f
data 3 1f 6d 9b 20 ea bb e9 f6 af 15 ef 33 72 aa b0 f1 f4 28 e3 0e 86 17 70 9c da 3d 2b 38 9a e2 0b 63
data 3 f8 1f 13 4d 8f 1d c5 ca 6b f0 89 24 9b 11 28 60 2f e8 b1 72 39 73 80 a7 79 c7 d5 89 c7 69 a2 28
data 3 df a9 19 b6 74 61 33 2c 23 f7 51 f6 fb 9f 34 df b4 99 fa 44 b9 16 f5 e2 33 52 5b 03 6d 69 ed db
data 3 c8 c4 af 56 4b 97 b2 1c 62 c3 d9 db 8d 5c 57 23 1c e8 16 b3 bc 50 ee 45 ce 9e eb 39 c3 7a fb ef
data 3 ec d5 89 87 3d 3d 58 78 fa e1 1a d2 8f 4c 58 21 a5 3d e9 b9 a9 32 91 89 45 01 c8 39 7d b2 1d 64
data 3 0b 40 35 7c 57 87 27 f7 23 d8 62 95 66 98 5c 73 12 46 f3 99 e1 97 5f a3 75 a8 73 d6 e5 6a 18 88
data 3 93 03 6f 8d 97 43 27 f5 75 ae eb 11 72 2e 49 63 82 1b 1a be 7b 12 f2 20 b0 cd cb ef 1f 77 2c 0d
data 3 ad cf 77 29 1d 7d d8 5a 37 49 16 f7 c9 4f 3d 99 9b c6 73 fe 01 06 ca bb 7d 38 f9 fb 44 e6 3e a7
data 3 09 8c 16 30 ff af 31 34 55 f9 42 fe 5f 14 a2 a8 18 29 e7 2e 2d d4 64 fb 5b 96 79 a0 e2 e5 cb cf
data 3 6e 98 1d df 7f 5e 12 ac 9e 41 98 be 45 c4 03 94 5b b2 cc 76 2d 0b 6e 46 d1 ea ce 0d cf 9a 47 4a
data 3 f4 45 95 80 00 bb 4b 6a 9e bf b3 cc 31 46 fe 76 e6 a1 10 b3 86 aa 29 47 4a a2 7f 9d d1 f7 6c 9c
data 3 cd 03 b0 df f1 98 f5 5c 25 af 0e e4 5c 9a 4a 90 46 24 b7 57 b3 f5 6a 7b 95 e7 5d 0b 4e de 94 6d
data 3 1f 17 3a 6b f7 6f 6c ea 00 ff ac 32 ad de ae 6c 02 df ba 47 e8 9f b4 ae 18 f8 74 d0 cf 2e cb 4e
data 3 e7 5c 66 b1 46 86 6d 9e 09 fb 57 6a 32 c0 6e 07 81 73 be cd d2 ba bc 77 8f df 94 04 d9 d9 9d 89
data 3 c9 48 62 06 02 07 35 1e 81 be 49 3f b5 97 cb 8d d2 c6 25 bd 8a 16 4c 0f ad 04 df 3f 56 83 78 c1
data 3 82 16 e9 3d d8 a6 db 3e 11 af e1 22 da 8e 04 2b 80 33 5b 2f 46 7c 6b 57 08 24 30 20 5a e1 b1 c7
data 3 e6 cf a5 64 8e f0 75 54 2b 17 21 17 d0 b8 c1 60 d2 37 52 b2 88 c8 5b a0 c8 26 f7 ee 76 1d fe 8a
data 3 de 5e 66 53 c4 06 af e9 94 bb fe c2 3f 9c 4e 4b 8e 2b 54 0e 27 d2 5e 07 53 49 d2 57 a4 f9 9b 49
data 3 83 0c 7a 2c 1b 55 dd c0 de 7a 59 78 15 ec 9f e9 a7 4e 5a 00 74 c8 64 88 39 5e fb 16 da a7 1a 3a
data 3 88 9f 5e fe c9 28 a3 d0 dc 9d 51 ba c8 7f 99 0f 69 52 73 ea c0 6d b3 97 8b 9e 0c 60 58 b8 46 65
data 3 54 0b c7 f6 2d 46 4f fd a8 23 aa 7c e5 58 1c 03 fc 4d 81 e9 70 17 36 b5 4d a2 14 8e 78 01 76 28
data 3 ce 70 79 81 16 a7 54 54 b3 bd d2 77 38 79 f2 9f ce e0 28 4a 09 24 eb e4 b2 18 da f4 1c d0 c3 9c
data 3 ef 8c 78 6a 42 bc 99 6f 39 81 0b 14 4b 08 3f 95 91 5f 51 e6 3b 9c 2f 52 37 d6 45 53 31 8c 7a c7
data 3 9e e5 ef e4 c9 74 8e 3b 41 42 b0 dc cd 70 81 68 99 a0 a9 04 39 8b 27 ae 37 94 91 b5 cd 1a 15 74
data 3 14 49 75 68 0b 8d dc 83 1d 5d 37 c9 95 bb 88 97 8c 9f 7e 38 c6 a2 cf e2 5e 4f 6b de 3e f3 b1 dc
00000 65e51da2967935b435ff5f2183901b8672027ec22300d2de549779f77334dfbb
00001 e487a28b41bac8837561aa887690c3c9577d6b50a6e5e7a47f2042b47553112b
00002 b9c1c758a3c97d3fccff0537b7d6f9ef313aa5d9db83ffe61efb6ddd541e2d13
00003 57398b5f5f26fd10b092f9d11c1ff93b8b6a9defbf5e2223b916b9dcc6a1dbb0
00004 23d00ca1af2ffaa2900fe7c2982e4be0f13cdb91ab90ef6bc1fe5c894bf92f9c
00005 5aab302ddabb8896ab02d4f60c232e84031ceb654935b0c00f712e9d35dd5044
00006 9209eb7b814444a7ea2a5daeb1e6605fb559c98c264f6394280cc5432f736c98
00007 eeec105ea6fbf4dfc3bc6cb456ffaa6a723683376f04e10e97477917073fe6ce
00008 4ebf73b5d103bfb04d606b5baa7d2836f9974e5fc6a457bc870116cde8b522df
00009 ae1b23f6070e7bf9bc69027622e096f1fcc09a5f932c216ad5cfd5e28bfd79ca
$
Dieharder testilista ressu2twist pseudorandom generaattorista: dieharder ok, muutama weak ja ei failed:eja suurissa tiedostoissa.
'input' = "ressu2twist", 'filesize' = "500m", 'filename' = "newressusample2778.rnd", 'weak' = "5", 'failed' = "1"
'input' = "ressu2twist", 'filesize' = "600m", 'filename' = "newressusample2779.rnd", 'weak' = "8", 'failed' = "2"
'input' = "ressu2twist", 'filesize' = "700m", 'filename' = "newressusample2780.rnd", 'weak' = "5", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "800m", 'filename' = "newressusample2781.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "900m", 'filename' = "newressusample2782.rnd", 'weak' = "8", 'failed' = "1"
'input' = "ressu2twist", 'filesize' = "1g", 'filename' = "newressusample2783.rnd", 'weak' = "3", 'failed' = "1"
'input' = "ressu2twist", 'filesize' = "1g100m", 'filename' = "newressusample2784.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g200m", 'filename' = "newressusample2785.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g300m", 'filename' = "newressusample2786.rnd", 'weak' = "1", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g400m", 'filename' = "newressusample2787.rnd", 'weak' = "0", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g500m", 'filename' = "newressusample2788.rnd", 'weak' = "4", 'failed' = "1"
'input' = "ressu2twist", 'filesize' = "1g600m", 'filename' = "newressusample2789.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g700m", 'filename' = "newressusample2790.rnd", 'weak' = "4", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "1g800m", 'filename' = "newressusample2791.rnd", 'weak' = "7", 'failed' = "1"
'input' = "ressu2twist", 'filesize' = "1g900m", 'filename' = "newressusample2792.rnd", 'weak' = "2", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "2g", 'filename' = "newressusample2793.rnd", 'weak' = "5", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "3g", 'filename' = "newressusample2794.rnd", 'weak' = "3", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "4g", 'filename' = "newressusample2795.rnd", 'weak' = "1", 'failed' = "0"
'input' = "ressu2twist", 'filesize' = "5g", 'filename' = "newressusample2796.rnd", 'weak' = "2", 'failed' = "0"
Vielä satunnaisuutta ressu2twist generaattorilla:
$ ./newressu --ressu2twist
00000 97012444102407788340267540519313056532607654063931610847036438082
00001 98649208498167169566177225621238699856816713087763493593959549374
00002 69310498922985186301871846630085994665595163512419208272134600903
00003 96139140967401247215761519708794100411697096648224731288486707361
00004 57572337836371786813024524739843379385983343549997012755834167559
00005 55656248944311459538961285615864423250930141563621549234124875963
00006 47175878589975997515322804227759286750190797730133449580624493986
00007 24045292500648098243161140595704526558693648443527733894821995285
00008 99455943065099852048076347542492705346556519891431654094159969073
00009 92903134932749129398699576971062767644868831486048109060567885495
$
Edellisessä versiossa copy reverse:ssä käytettiin clock() funktiolla prosessin aikaa, lisätty tuo samainen funktio ressu2_round funktioon. Seuraavassa mallituloste clock():sta:
$ cat clock.c
#include <stdio.h>
#include <time.h>
void main(int argc, char *argv[])
{
int c, d;
unsigned char buffer[32];
fprintf(stdout,"clock:%02lu\n", (unsigned long)clock());
for(c = 0; c < 10; c++) {
for(d = 0; d < sizeof(buffer); d++)
buffer[d] = clock() & 0xff;
for(d = 0; d < sizeof(buffer); d++)
fprintf(stdout,"%02x", buffer[d]);
fprintf(stdout,"\n");
}
}
$ cc clock.c -o clock
$ ./clock
clock:907
d0d1d1d2d2d3d4d4d5d5d6d6d7d7d8d9d9dadadbdbdcdcdddededfdfe0e0e1e1
f1f2f2f3f3f4f4f5f5f6f7f7f8f8f9f9fafbfbfcfcfdfdfefeff000001010202
12131314141515161717181819191a1d1e1f1f20202121222223232425252626
313132323334343535363637373838393a3a3b3b3c3c3d3d3e3f3f4040414142
494a4a4b4b4c4c4d4e4e4f4f5050515152535354545555565657575859595a5a
6262636364646565666667686869696a6a6b6b6c6d6d6e6e6f6f707071717273
7a7a7b7b7c7d7d7e7e7f7f8080818182838384848585868687888889898c8c8d
949595969697979899999a9a9b9b9c9c9d9d9e9f9fa0a0a1a1a2a2a3a4a4a5a5
acadaeaeafafb0b0b1b1b2b2b3b4b4b5b5b6b6b7b7b8b9b9bababbbbbcbcbdbd
c5c5c6c6c7c8c8c9c9cacacbcbcccccdcececfcfd0d0d1d1d2d3d3d4d4d5d5d6
$
Ja uusi versio ressu2 rutiineista: uusi koodi on rakennettu g-muuttujan ympärille ressu2_round():ssa.
static int randomness = 0;
#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )
...
static void ressu2_round(int size, unsigned char *buffer) // ressu JariK 2013
{
int c, d, byte;
unsigned char e;
static int f = 0, prevbyte = -1;
static unsigned char g = 0;
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; // exclusive or data with byte
if(prevbyte != byte) {
prevbyte = byte;
randomness++;
}
}
for(d = 0; d < size; d++) { // swap
g = g << 1;
g ^= buffer[d];
g ^= (clock() & 0xff); // processor time (for randomness)
f = (f + g + 2) % size;
e = buffer[d];
buffer[d] = buffer[f];
buffer[f] = e;
}
}
}
#define DEBUG16A 2
#define aDEBUG17 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)
{
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;
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 DEBUG17
ressu_dump("ressu2", sizeof(ressu), ressu, 32);
#endif
#ifdef DEBUG16A
if(stats) {
fprintf(stdout,"rounds:%d", d);
fprintf(stdout,", randomness:%d", randomness);
fprintf(stdout,", clocksused:%d", clocksused);
fprintf(stdout,"\n");
}
#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 DEBUG17
ressu_dump("data 1", size, buffer, 32);
#endif
}
dbs3.c lähdekoodi kokonaisuudessaan
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <poll.h>
#include <fcntl.h>
#include <errno.h>
#include "sha256.h"
char *programname = "DBS3 version 0.14 ©";
unsigned char *procname;
unsigned char *myport = "5000";
unsigned char homedir[128];
unsigned char *htmlin;
int htmlinlen = 128;
unsigned char *htmlparams = NULL;
int dbs_output = 0;
void dbs_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
int c;
if(dbs_output) {
fprintf(stdout,"\n");
dbs_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);
}
#include <stdarg.h>
unsigned char log_filename[128] = "dbs3.log";
unsigned char log_childfile[128] = "dbs3child.log"; // for zombihunt
int log_mode = 1; // 1 = main, 2 = child
#include <time.h>
void log_wait(); // cross-use with log_printf() routines
void log_post();
void log_printf_valist(FILE *fp1, const char *format, va_list ap) // JariK 2025
{
int count;
static char *printbuf = NULL;
static int printbuf_len = 0;
static int printtime = 1;
va_list ap2;
va_copy(ap2, ap);
count = vsnprintf(printbuf, printbuf_len, format, ap) + 1;
if(printbuf_len < count) {
printbuf_len = count;
printbuf = realloc(printbuf, printbuf_len);
count = vsnprintf(printbuf, printbuf_len, format, ap2) + 1;
}
// print all characters from printbuf.
// print all characters to log adding time and date.
fputs(printbuf, fp1);
FILE *fp2;
if((fp2 = fopen(log_filename, "a")) != NULL) {
if(printtime) {
time_t now = time(NULL);
unsigned char timestamp[32];
log_wait(); // JariK 2025
strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S%Z", localtime((time_t *)&now));
fputs(timestamp, fp2);
fputc(' ', fp2);
if(log_mode == 2)
fprintf(fp2,"%d ",getpid()); // process id of child
printtime = 0;
}
fputs(printbuf, fp2);
fclose(fp2);
if(printbuf[strlen(printbuf) - 1] == '\n') {
printtime = 1;
log_post(); // JariK 2025
}
}
if(log_mode == 2) {
if((fp2 = fopen(log_childfile, "a")) != NULL) {
fputs(printbuf, fp2);
fclose(fp2);
}
}
}
#ifdef OLD1
void log_printf(const char *format, ...) // JariK 2025
{
int count;
va_list args;
static char *printbuf = NULL;
static int printbuf_len = 0;
static int printtime = 1;
va_start(args, format);
count = vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
if(printbuf_len < count) {
printbuf_len = count;
printbuf = realloc(printbuf, printbuf_len);
va_start(args, format);
count = vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
}
// print all characters from printbuf.
// print all characters to log adding time and date.
fputs(printbuf, stdout);
FILE *fp1;
if((fp1 = fopen(log_filename, "a")) != NULL) {
if(printtime) {
time_t now = time(NULL);
unsigned char timestamp[32];
log_wait(); // JariK 2025
strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S%Z", localtime((time_t *)&now));
fputs(timestamp, fp1);
fputc(' ', fp1);
printtime = 0;
}
fputs(printbuf, fp1);
fclose(fp1);
if(printbuf[strlen(printbuf) - 1] == '\n') {
printtime = 1;
log_post(); // JariK 2025
}
}
if(log_mode == 2) {
if((fp1 = fopen(log_childfile, "a")) != NULL) {
fputs(printbuf, fp1);
fclose(fp1);
}
}
}
#endif // end of #ifdef OLD1
void log_printf(const char *format, ...) // JariK 2025
{
va_list args;
va_start(args, format);
log_printf_valist(stdout, format, args);
//fprintf(stdout,format, args);
va_end(args);
}
void log_errprintf(const char *format, ...) // JariK 2025
{
va_list args;
va_start(args, format);
log_printf_valist(stderr, format, args);
//fprintf(stdout,format, args);
va_end(args);
}
#include <semaphore.h>
#include <signal.h>
static sem_t *logmutex = NULL;
static char logsemname[32] = "dbs3log.sem";
void log_wait() // JariK 2025
{
signal(SIGINT, SIG_IGN);
if(logmutex == NULL) {
if((logmutex = sem_open(logsemname, 0, 0644, 1)) == SEM_FAILED) {
if((logmutex = sem_open(logsemname, O_CREAT, 0644, 1)) == SEM_FAILED) {
//if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {
log_errprintf("%s: log_wait: cannot sem_open()", procname);
log_errprintf(" errno %d", errno);
log_errprintf("(%s)\n", strerror(errno));
perror("sem_open");
}
}
}
if(sem_wait(logmutex) == -1) {
log_errprintf("%s: log_wait: cannot sem_wait()", procname);
log_errprintf(", errno: %d", errno);
log_errprintf("(%s)\n", strerror(errno));
perror("sem_wait");
}
}
void log_post() // JariK 2025
{
if(sem_post(logmutex) == -1) {
log_errprintf( "%s: log_post: cannot sem_post()", procname);
log_errprintf( ", errno: %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("sem_post");
}
sem_close(logmutex);
logmutex = NULL;
signal(SIGINT, SIG_DFL);
}
void log_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
int c;
for(c = 0; c < len; c++) {
if(c % linelen == 0) {
if(c > 0)
log_printf("\n");
log_printf("%-10s", header);
}
log_printf(" %02x", buf[c]);
}
log_printf("\n");
}
static void log_clear()
{
}
static void log_dump_string(unsigned char *line)
{
}
#define HTML_BUFFERS 9
int html_now = 0;
unsigned char *html[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int html_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void html_set(int bufno)
{
html_now = bufno;
if(html[bufno] == NULL) {
html_size[bufno] = 10;
html[bufno] = malloc(html_size[bufno]);
}
}
int html_get()
{
return(html_now);
}
unsigned char *html_get_string(int bufno)
{
return(html[bufno]);
}
void html_clear()
{
html_set(html_now);
html[html_now][0] = '\0';
}
void html_clear_all()
{
int c;
for(c = 0; c < HTML_BUFFERS; c++) {
html_set(c);
html_clear();
}
}
static void html_printf_valist(const char *format, va_list ap)
{
int count;
static char *printbuf = NULL;
static int printbuf_len = 0;
va_list ap2;
va_copy(ap2, ap);
count = vsnprintf(printbuf, printbuf_len, format, ap) + 1;
if(printbuf_len < count) {
printbuf_len = count;
printbuf = realloc(printbuf, printbuf_len);
count = vsnprintf(printbuf, printbuf_len, format, ap2) + 1;
}
if(html_size[html_now] <
strlen(html[html_now]) +
strlen(printbuf) + 1) {
html_size[html_now] =
strlen(html[html_now]) +
strlen(printbuf) + 1;
html[html_now] = realloc(html[html_now], html_size[html_now]);
}
strcpy(html[html_now] + strlen(html[html_now]), printbuf);
}
void html_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
html_printf_valist(format, args);
//fprintf(stdout,format, args);
va_end(args);
}
void html_buf_printf(int bufno, const char *format, ...)
{
int save_html;
va_list args;
save_html = html_get();
html_set(bufno);
va_start(args, format);
html_printf_valist(format, args);
va_end(args);
html_set(save_html);
}
int indent;
int printedchars = 0;
#define aDEBUG28
void html_out_crlf()
{
if(printedchars) {
#ifdef DEBUG28
fprintf(stdout,"(%d)", indent * 8 + printedchars);
#endif
html_printf("\n");
#ifdef DEBUG28
fprintf(stdout,"\n");
#endif
for(int c = 0; c < indent; c++) {
html_printf("\t");
#ifdef DEBUG28
fprintf(stdout,"\t");
#endif
}
printedchars = 0;
}
}
#define aDEBUG31 2
void html_parse_name(int size, unsigned char *name, unsigned char **p2)
{
int count;
unsigned char *p, *n;
p = *p2;
count = 0;
n = name;
while(isalpha(*p) || isdigit(*p) || *p == '!') {
if(++count < size)
*n++ = *p;
p++;
count++;
}
*n = '\0';
#ifdef DEBUG31
fprintf(stdout,"[name:%s]", name);
#endif
}
#define aDEBUG36 2
#define aDEBUG37 2
void html_indent(unsigned char *p2) // 2021 JariK
{
int space, ch, tags, tagfound, intag, inchar;
unsigned char *p, *q, *q2, name[32], tag[48];
p = p2;
ch = 0;
indent = 0;
inchar = 0;
while(*p != '\0') {
space = 0;
while(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ') {
p++;
space = 1;
}
if(!strncmp(p,"<br>", 4)) {
p += 4;
html_printf("<br>");
#ifdef DEBUG36
fprintf(stdout,"<br>");
#endif
printedchars += 4;
while(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
p++;
#ifdef DEBUG36
fprintf(stdout,"[nextchar:%c]", *p);
#endif
if(strncmp(p,"</", 2))
html_out_crlf();
}
if(!strncmp(p,"</", 2)) { // Check for end tag
q2 = p;
p += 2;
q = p;
html_parse_name(sizeof(name), name, &q);
q = q2 - 1;
tags = 0;
tagfound = 0;
// Search for start tag backward
sprintf(tag,"<%s", name);
while(q >= p2) {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q--;
}
if(tags && indent > 0) {
indent--;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]", indent);
fprintf(stdout,"[tagfound:%d]", tagfound);
#endif
html_out_crlf();
}
html_printf("</");
#ifdef DEBUG36
fprintf(stdout,"</");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
printedchars += 2;
} else if(*p == '<') { // Check for start tag
p++;
q = p;
html_parse_name(sizeof(name), name, &q);
tags = 0;
tagfound = 0;
// Search for end tag forward
sprintf(tag,"</%s", name);
while(*q != '\0') {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q++;
}
html_out_crlf();
if(tags && tagfound) {
indent++;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]", indent);
fprintf(stdout,"[tagfound:%d]", tagfound);
#endif
}
html_printf("<");
#ifdef DEBUG36
fprintf(stdout,"<");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
printedchars++;
} else if((isprint(*p) || *p>=128) && *p!='\0') {
if(!inchar && !intag) {
inchar = 1;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]", inchar);
#endif
//html_out_crlf();
}
int count = 0;
for(q = p; (isprint(*q) || *q>=128) && *q!='\0'; q++) {
if(*q == '\r' || *q == '\n' || *q == '\t' || *q == ' ')
break;
#ifdef DEBUG36
fprintf(stdout,"%c", *q);
#endif
count++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)", count);
#endif
}
int chars = 0;
// calculate number of chars
q = p;
while((*q != '<' && (isprint(*q) || *q >= 128)) && *q != '\0') {
if(*q == '\r' || *q == '\n' || *q == '\t' || *q == ' ')
break;
if(*q < 0x80 || *q > 0xbf) // utf8 too
chars++;
if(*q == '>')
break;
q++;
}
// print line break if needed
if(indent * 8 + printedchars + chars > 100 && !intag) {
html_out_crlf(); // print nl+indent
space = 0;
}
// print space if needed
if(ch != '>' && // no space after tag
*p != '<' && // no space before tag
printedchars > 0 &&
space) {
html_printf(" ");
#ifdef DEBUG36
fprintf(stdout," ");
#endif
space = 0;
}
//print the string
while((*p != '<' && (isprint(*p) || *p >= 128)) && *p != '\0') {
if(*p == '>') {
intag = 0;
}
if(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
break;
ch = *p;
html_printf("%c", *p);
#ifdef DEBUG36
fprintf(stdout,"%c", *p);
#endif
printedchars++;
if(*p == '>') {
p++;
break;
}
p++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)", chars);
#endif
} //while(*p!='\0')
#ifdef DEBUG37
fprintf(stdout,"%s", html[html_now]);
#endif
}
#define backlog 64
int s = -1, news;
//char cert_file[128] = "/etc/letsencrypt/live/moijari.com/fullchain.pem";
//char privatekey_file[128] = "/etc/letsencrypt/live/moijari.com/privkey.pem";
char cert_file[128] = "fullchain.pem";
char privatekey_file[128] = "privkey.pem";
#define HTMLTIMEFORMAT "%a, %d %b %Y %H:%M:%S GMT"
unsigned char htmlmethod[10];
unsigned char htmlpath[128];
unsigned char htmlversion[32];
unsigned char htmlfilename[64];
unsigned char htmlfileextension[10];
unsigned char htmlhost[32];
unsigned char htmluseragent[1024];
unsigned char htmlcookie[1024];
unsigned char htmlreferer[128];
unsigned char htmlsessionid[33];
unsigned char htmldigest[HashLen * 2 + 1];
unsigned char htmlmode[10];
unsigned char htmllanguage[10];
unsigned char htmltimeshort[32];
unsigned char htmltime[32];
unsigned char htmlsslcipher[64];
static unsigned char *dbs_html_get_request_line(unsigned char *name, int lenbuffer, unsigned char *buffer)
{
int len;
unsigned char *p, *q, tag[32];
p = htmlin;
#ifdef DEBUG11
fprintf(stdout,"Data:");
dump_string(stdout, p);
fprintf(stdout,"\n");
#endif
sprintf(tag, "\r\n%s:", name);
while(*p != '\0') {
if(!strncmp(p, tag, strlen(tag))) {
p += strlen(tag);
while(isblank(*p))
p++;
q = buffer;
len = 0;
while(*p != '\r' && *p != '\n' && *p != '\0') {
if(++len < lenbuffer)
*q++ = *p;
p++;
}
*q = '\0';
return(buffer);
}
if(*p != '\0')
p++;
}
return(NULL);
}
static void dbs_html_get_request_line_num(unsigned char *name, int lenbuffer, unsigned char *buffer)
{
unsigned char *p;
if((p = dbs_html_get_request_line(name, lenbuffer, buffer)) == NULL)
sprintf(buffer,"0");
#ifdef OLD1
else {
int len = 0;
unsigned char *n = buffer;
while(isdigit(*p)) {
if(++len < lenbuffer)
*n++ = *p;
p++;
}
*n = '\0';
}
#endif
}
void dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value)
{
int len;
unsigned char *p, *n;
value[0] = '\0';
p = htmlcookie;
while(*p != '\0') {
while(isblank(*p))
p++;
if(!strncmp(p, name, strlen(name))) {
p += strlen(name);
while(isblank(*p))
p++;
if(*p == '=')
p++;
while(isblank(*p))
p++;
n = value;
len = 0;
while(*p != ';' && (isprint(*p) || *p >= 0x80)) { // utf8 chars too
if(++len < valuelen)
*n++ = *p;
p++;
}
*n = '\0';
return;
}
while(*p != ';' && *p != '\n' && *p != '\0')
p++;
if(*p == ';')
p++;
while(isblank(*p))
p++;
}
}
static void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2)
{
int len;
unsigned char *p;
p = *p2;
len = 0;
while(*p != '\0' && !isblank(*p) && *p != '\n' && *p != '\r') {
if(++len < buflen) {
*buf++ = *p;
}
p++;
}
*buf = '\0';
while(isblank(*p))
p++;
*p2 = p;
}
static void dbs_parse_filename(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '/') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
void dbs_parse_extension(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '.') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
static unsigned char *dbs_html_get_params()
{
int ok = 0;
unsigned char *p = htmlin;
while(*p != '\0') {
if(!strncmp(p,"\r\n\r\n", 4)) {
p += 4;
ok = 1;
break;
}
p++;
}
if(ok)
return(p);
else
return(NULL);
}
static void dbs_time_vars()
{
}
#define HTML_HEADER_BUFFER 0
#define HTML_PAYLOAD_BUFFER 1
#define HTML_FOREIGN_BUFFER 2
#define HTML_QUERY_BUFFER 3
#define HTML_LAST_BUFFER 4
void dba_app_footer()
{
html_printf("<p>%s", programname);
html_printf(", sha256(%s)", htmldigest);
html_printf("</p>");
#ifdef OLD1
html_printf("<br><br>%s, sha256(%s)<br><br>",
programname, htmldigest);
#endif
}
static void dba_loop()
{
unsigned char buffer30[30];
log_printf("entering dba_loop()\n");
if(!strcmp(htmlfileextension,"ico") ||
!strcmp(htmlfileextension,"png")) {
html_clear_all();
html_set(HTML_HEADER_BUFFER);
html_printf("HTTP/1.0 404 ERROR\r\n");
html_printf("Location: \r\n");
html_printf("Server: %s\r\n", programname);
return;
}
log_printf("fetching cookies\n");
dbs_get_cookie("terttu_sessionid", sizeof(htmlsessionid), htmlsessionid);
log_printf("htmlsessionid: \"%s\"\n", htmlsessionid);
dbs_get_cookie("terttu_mode", sizeof(htmlmode), htmlmode);
log_printf("htmlmode: \"%s\"\n", htmlmode);
dbs_get_cookie("terttu_language", sizeof(htmllanguage), htmllanguage);
log_printf("htmllanguage: \"%s\"\n", htmllanguage);
//dbs_get_cookie("ääkköskooki", sizeof(buffer30), buffer30);
//log_printf("ääkköskooki: \"%s\"\n", buffer30);
log_printf("end fetching cookies\n");
html_set(HTML_HEADER_BUFFER);
html_printf("HTTP/1.0 200 OK\r\n");
html_printf("Location: \r\n");
html_printf("Server: %s\r\n", programname);
html_set(HTML_PAYLOAD_BUFFER);
html_printf("<!doctype html>\r\n");
html_printf("<html lang=\"fi\">");
html_printf("<head>");
html_printf("<meta charset=\"utf-8\">");
html_printf("<title>dbs3</title>");
html_printf("<meta name=\"author\" content=\"Jari Kuivaniemi\">");
html_printf("<meta name=\"copyright\" content=\"Jari Kuivaniemi\">");
html_printf("<meta name=\"format-detection\" content=\"telephone=no\">"); // Safari
html_printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
html_printf("</head>");
html_printf("<body>");
html_printf("<h1>Hello world!</h1>");
html_printf("<p>Tämä on artikkelin <a href=\"https://moijari.com?p=2990\">https://moijari.com?p=2990</a> testiohjelma.");
html_printf(" Ohjelma löytyy tästä linkistä <a href=\"https://moijari.com:5008\">https://moijari.com:5008</a>.</p>");
FILE *fp1;
unsigned char buffer[1024];
if((fp1 = popen("./newressu","r")) != NULL) {
html_printf("<p>Seuraava kappale sisältää ressun tekemiä satunnaisbittejä.");
html_printf(" Ne ovat tässä vain tilan täytteeksi.</p>");
html_printf("<code>");
while(fgets(buffer, sizeof(buffer), fp1) != NULL) {
html_printf("%s<br>", buffer);
}
html_printf("</code>");
pclose(fp1);
}
//html_printf("<p>Tässä on <b>Boldia tekstiä</b>. Tämä taas <u>alleviivattua tekstiä</u>.</p>");
//html_printf("<p>Tämä on artikkelin https://moijari.com/?p=2990 testiohjelma.");
//html_printf(" Ohjelma löytyy linkistä https://moijari.com:5008/.</p>");
html_set(HTML_LAST_BUFFER);
html_clear();
dba_app_footer();
html_printf("</body>");
html_printf("</html>");
time_t now;
unsigned char timebuf[128];
html_set(HTML_HEADER_BUFFER);
now = time(NULL);
strftime(timebuf, sizeof(timebuf), HTMLTIMEFORMAT, gmtime(&now));
html_printf("Date: %s\r\n", timebuf);
//html_printf("Set-Cookie: ääkköskooki=99öökköskooki; Max-Age=360\r\n");
}
static void dba_loop2()
{
int c, len;
log_printf("entering dba_loop2()\n");
html_set(HTML_HEADER_BUFFER);
len = strlen(html_get_string(1)) +
strlen(html_get_string(2)) +
strlen(html_get_string(3)) +
strlen(html_get_string(4)) +
strlen(html_get_string(5)) +
strlen(html_get_string(6)) +
strlen(html_get_string(7)) +
strlen(html_get_string(8));
html_printf("Content-Length: %d\r\n", len);
unsigned char hash[HashLen];
HashCtx ctx;
#define DEBUG46 2
#ifdef DEBUG46
FILE *fp1;
char *filename = "dbs3sha.deb";
if((fp1 = fopen(filename, "w")) == NULL) {
log_errprintf("%s: cannot open file %s\n", procname, filename);
exit(1);
}
#endif
HashInit(&ctx);
for(c = 1; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)) > 0) {
HashUpdate(&ctx, html_get_string(c), strlen(html_get_string(c)));
//fprintf(stdout,"%d \"%s\"\n", c, html_get_string(c));
#ifdef DEBUG46
fwrite(html_get_string(c), strlen(html_get_string(c)), 1, fp1);
#endif
}
}
HashFinal(hash, &ctx);
#ifdef DEBUG46
fclose(fp1);
#endif
html_printf("SHA256: ");
for(c = 0; c < sizeof(hash); c++) {
html_printf("%02x", hash[c]);
}
html_printf("\r\n");
html_printf("\r\n\r\n");
log_printf("exiting dba_loop2()\n");
}
#define DEBUG25 2
static void dbs_run_loop()
{
unsigned char *p;
p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
log_printf("htmlmethod: \"%s\"\n", htmlmethod);
dbs_html_parse_string(sizeof(htmlpath), htmlpath, &p);
log_printf("htmlpath: \"%s\"\n", htmlpath);
dbs_html_parse_string(sizeof(htmlversion), htmlversion, &p);
log_printf("htmlversion: \"%s\"\n", htmlversion);
dbs_parse_filename(sizeof(htmlfilename), htmlfilename, htmlpath);
log_printf("htmlfilename: \"%s\"\n", htmlfilename);
dbs_parse_extension(sizeof(htmlfileextension), htmlfileextension, htmlfilename);
log_printf("htmlfileextension: \"%s\"\n", htmlfileextension);
htmlparams = dbs_html_get_params();
if(htmlparams != NULL)
log_printf("htmlparams: \"%s\"\n", htmlparams);
if(dbs_html_get_request_line("Host", sizeof(htmlhost), htmlhost) == NULL)
htmlhost[0] = '\0';
log_printf("htmlhost: \"%s\"\n", htmlhost);
if(dbs_html_get_request_line("User-Agent", sizeof(htmluseragent), htmluseragent) == NULL)
htmluseragent[0] = '\0';
log_printf("htmluseragent: \"%s\"\n", htmluseragent);
if(dbs_html_get_request_line("Cookie", sizeof(htmlcookie), htmlcookie)==NULL)
htmlcookie[0] = '\0';
log_printf("htmlcookie: \"%s\"\n", htmlcookie);
if(dbs_html_get_request_line("Referer", sizeof(htmlreferer), htmlreferer)==NULL)
htmlcookie[0] = '\0';
log_printf("htmlreferer: \"%s\"\n", htmlreferer);
html_clear_all();
log_printf("enter dba_loop()\n");
dba_loop();
log_printf("html prettyprinter\n");
#ifdef DEBUG25
log_printf("buffers1:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
for(int c = 1; c < HTML_BUFFERS - 2; c++) {
p = html_get_string(c);
html_set(HTML_BUFFERS - 2);
html_printf("%s", p);
html_set(c);
html_clear();
}
#ifdef DEBUG25
log_printf("buffers2:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
p = html_get_string(HTML_BUFFERS - 2);
html_set(HTML_BUFFERS - 1);
html_indent(p);
html_set(HTML_BUFFERS - 2);
html_clear();
#ifdef DEBUG25
log_printf("buffers3:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
#ifdef DEBUG25
log_printf("html prettyprinter done.\n");
#endif
log_printf("exit dba_loop2()\n");
dba_loop2();
}
#define DEBUG42 2
void init_child()
{
// open file for hunting zombies
sprintf(log_childfile, "dbs3pid%d.log", getpid());
}
void exit_child()
{
// if process ends normally
// delete child's logfile
log_printf("unlink %s\n", log_childfile);
unlink(log_childfile);
}
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
static void dbs_server_vars(struct sockaddr_in sa_cli, int addr_size, char *name)
{
}
#include <sys/time.h>
unsigned long long dbs_get_useconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec + 1000000 * tv.tv_sec);
}
static void dbs_query_vars()
{
}
static sem_t *criticalmutex = NULL;
static char criticalsemname[32] = "dbs3critical.sem";
void critical_wait() // JariK 2025
{
signal(SIGINT, SIG_IGN);
if(criticalmutex == NULL) {
if((criticalmutex = sem_open(criticalsemname, 0, 0644, 1)) == SEM_FAILED) {
if((criticalmutex = sem_open(criticalsemname, O_CREAT, 0644, 1)) == SEM_FAILED) {
//if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {
log_errprintf( "%s: critical_wait(): cannot sem_open()", procname);
log_errprintf(" errno %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("sem_open");
}
}
}
if(sem_wait(criticalmutex) == -1) {
log_errprintf( "%s: critical_wait(): cannot sem_wait()", procname);
log_errprintf( ", errno: %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("sem_wait");
}
}
void critical_post() // JariK 2025
{
if(sem_post(criticalmutex) == -1) {
log_errprintf( "%s: critical_post(): cannot sem_post()", procname);
log_errprintf( ", errno: %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("sem_post");
}
sem_close(criticalmutex);
criticalmutex = NULL;
signal(SIGINT, SIG_DFL);
}
void dbs_run_critical_sections()
{
log_printf("critical_wait()\n");
critical_wait();
log_printf("critical_post()\n");
critical_post();
}
static int server_getaddrinfo(unsigned char *myport, struct addrinfo **res)
{
int status;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
log_printf("getaddrinfo()\n");
if ((status = getaddrinfo(NULL, myport, &hints, res)) != 0) {
#ifdef OLD1
fprintf(stderr, "%s: getaddrinfo error: %s",
procname, gai_strerror(status));
fprintf(stderr,", error code %d\n", status);
#endif
log_errprintf( "%s: getaddrinfo error: %s",
procname, gai_strerror(status));
log_errprintf( ", error code %d\n", status);
//fflush(stderr);
}
return(status);
}
static int server_socket(struct addrinfo *res)
{
int s;
log_printf("socket()\n");
if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
log_errprintf("%s: socket()", procname);
log_errprintf(", errno: %d", errno);
log_errprintf("(%s)\n", strerror(errno));
perror("socket");
//fflush(stderr);
}
return(s);
}
static void server_bind(int s, struct addrinfo *res)
{
log_printf("bind()\n");
if(bind(s, res->ai_addr, res->ai_addrlen) == -1) {
int errerrno = errno;
if(errerrno == 98) {
fprintf(stdout,"%s cannot bind, waiting to bind", procname);
while(errerrno == 98) {
sleep(10);
fprintf(stdout,".");
fflush(stdout);
bind(s, res->ai_addr, res->ai_addrlen);
errerrno = errno;
}
fprintf(stdout,"bind done!\n");
//fflush(stdout);
} else {
int errerrno = errno;
log_errprintf("%s: cannot bind()", procname);
log_errprintf(", errno: %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("bind");
//fflush(stderr);
}
}
}
static int server_listen(int s)
{
int retval;
log_printf("listen()\n");
if((retval = listen(s, backlog)) == -1) { // ==!
int errerrno = errno;
log_errprintf("%s: cannot listen()", procname);
log_errprintf(", errno %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("listen");
//fflush(stderr);
}
return(retval);
}
static void server_close(int s)
{
log_printf("close()\n");
if(close(s) == -1) {
int errerrno = errno;
log_errprintf("%s: cannot close()", procname);
log_errprintf(", errno %d", errerrno);
log_errprintf( "(%s)\n", strerror(errerrno));
perror("close");
//fflush(stderr);
}
}
static int server_basic_socket()
{
int s;
struct addrinfo *res;
log_printf("server_getaddrinfo()\n");
server_getaddrinfo(myport, &res);
log_printf("server_socket()\n");
s = server_socket(res);
log_printf("server_bind()\n");
server_bind(s, res);
log_printf("freeaddrinfo()\n");
freeaddrinfo(res);
log_printf("server_listen()\n");
server_listen(s);
return(s);
}
#define DEBUG38 2
static void http_client(int news, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
unsigned char buffer10[10];
htmlparams = NULL;
htmlin[0] = '\0';
dbs_server_vars(sa_cli, addr_size, name);
while(htmlparams == NULL ||
clen - strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
struct pollfd fds;
fds.fd = news;
fds.events = POLLIN;
bytes = 0;
int retval = poll(&fds, 1, 1000 * 10);
log_printf("******poll: %d\n", retval);
if(retval > 0) { // -1 err, 0 expire
log_printf("read()\n");
if((bytes = read(news, htmlin + totalbytes, htmlinlen - totalbytes)) < 0) {
log_errprintf("%s: cannot read()\n", procname);
perror("read");
//fflush(stderr);
}
if(retval > 0)
reads++;
}
log_printf("(%d bytes)", bytes);
log_printf("%s", htmlin);
if(bytes == 0)
break;
if(bytes > 3 &&
!isprint(htmlin[0]) &&
!isprint(htmlin[1]) &&
!isprint(htmlin[2])) {
log_printf("https packet?\n");
htmlin[0] = '\0';
totalbytes = 0;
bytes = 0;
break;
}
*(htmlin + totalbytes + bytes) = '\0';
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin = realloc(htmlin, htmlinlen * 2 + 1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(!strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length", sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("htmlin:\"%s\"",htmlin);
if(totalbytes != 0) {
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"");
log_dump_string(htmlin);
log_printf("\"\n");
dbs_run_loop();
log_printf("buffers(html):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
if((bytes = write(news, html_get_string(c), strlen(html_get_string(c)))) == -1) {
log_errprintf("%s: cannot write() dbs_html[%d]\n", procname, c);
perror("write");
//fflush(stderr);
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n",html_get_string(c));
}
log_printf("\n");
}
dbs_query_vars();
}
int beepaccept = 1;
#define DEBUG45 2
#define aDEBUG57 2
static void http_server()
{
int quit, reset, addr_size;
struct sockaddr_in sa_cli;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// plus space for '\0'
htmlin = malloc(htmlinlen + 1);
reset = 1;
quit = 0;
for(;;) {
log_mode = 1;
if(quit) {
break;
}
if(reset) {
if(s != -1) {
log_printf("server_close()\n");
server_close(s);
}
log_printf("server_basic_socket()\n");
s = server_basic_socket();
reset = 0;
}
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
log_errprintf("%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
fprintf(stdout,"========================================\n");
log_printf("dbs_time_vars()\n");
dbs_time_vars();
if(beepaccept) {
fprintf(stderr,"\a\n");
fflush(stderr);
}
pid_t pid;
log_printf("fork start (parent)");
log_printf(" getpid:%d getppid:%d", getpid(), getppid());
log_printf("\n");
log_printf("fork()\n");
if((pid = fork()) < 0) {
log_errprintf("%s: cannot fork()", procname);
log_errprintf(", errno %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
fflush(stderr);
perror("fork");
fflush(stderr);
exit(1);
} else if(pid == 0) { // child
log_printf("init_child()\n");
init_child();
log_mode = 2; // child
log_printf("server_close()\n");
server_close(s);
log_printf("fork start (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("http_client()\n");
http_client(news, sa_cli, addr_size, "http");
dbs_run_critical_sections();
log_printf("server_close(news)\n");
server_close(news);
log_printf("fork end (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("exit_child()\n");
exit_child();
log_mode = 1;
exit(0);
}
log_printf("fork end (parent)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("server_close()\n");
server_close(news);
} // for(;;)
}
#ifdef OLD1
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int status, ok;
unsigned char buffer10[10];
SSL *ssl;
X509 *peer_cert;
unsigned long long useconds;
useconds = dbs_get_useconds();
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
log_printf("SSL_new()\n");
if((ssl = SSL_new(ctx)) == NULL) {
log_errprintf("\n%s: cannot SSL_new()", procname);
}
log_printf("SSL_set_fd()\n");
if(SSL_set_fd(ssl, news) != 1) {
log_errprintf("\n%s: cannot SSL_set_fd()\n", procname);
}
log_printf("SSL_accept()\n");
if((status = SSL_accept(ssl)) < 0) {
log_errprintf("%s: cannot SSL_accept(), retval: %d\n", procname, status);
}
log_printf("SSL_get_peer_certificate()");
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
while(htmlparams == NULL || clen - strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
int tries = 0;
for(;;) {
log_printf("SSL_read()\n");
bytes = SSL_read(ssl, htmlin + totalbytes, htmlinlen - totalbytes);
int errerrno, err, err2;
errerrno = errno;
err = SSL_get_error(ssl, bytes);
err2 = ERR_get_error();
log_printf("SSL_read()");
log_printf(", retval %d", bytes);
log_printf(", errno: %d", errerrno);
log_printf(", SSL_get_error(): %d", err);
log_printf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_printf(", %d", err2);
log_printf("\n");
if(bytes >= 0) {
reads++;
break;
}
if(bytes < 0) {
if(++tries < 5 && (err == 1 || err == 5)) {
usleep(1024 * 512 / 5);
log_printf(" try:%d", tries);
continue;
}
log_printf("cannot SSL_read()\n");
ok = 0;
break;
} // if(bytes
break;
} // for(;;)
log_printf("(%d bytes)\n", bytes);
log_printf("%s\n", htmlin);
if(!ok)
break;
*(htmlin + totalbytes + bytes) = '\0';
if(bytes == 0)
break;
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin = realloc(htmlin, htmlinlen * 2 + 1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(!strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"\n");
log_dump_string(htmlin);
log_printf("\"\n");
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
log_printf("SSL_write()\n");
if((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) < 1) {
log_errprintf("%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\n",
procname, c, status, SSL_get_error(ssl, status));
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n", html_get_string(c));
}
}
log_printf("SSL connection using %s\n", htmlsslcipher);
log_printf("dbs_query_vars()\n");
dbs_query_vars();
log_printf("SSL_free()\n");
SSL_free(ssl);
}
#endif
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name) // JariK 2025, 2022
{
int status, ok;
unsigned char buffer10[10], buffer[256];
SSL *ssl;
X509 *peer_cert;
unsigned long long useconds;
useconds = dbs_get_useconds();
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
log_printf("SSL_new()\n");
if((ssl = SSL_new(ctx)) == NULL) {
log_errprintf("\n%s: cannot SSL_new()", procname);
}
log_printf("SSL_set_fd()\n");
if(SSL_set_fd(ssl, news) != 1) {
log_errprintf("\n%s: cannot SSL_set_fd()\n", procname);
}
log_printf("SSL_accept()\n");
if((status = SSL_accept(ssl)) < 0) {
log_errprintf("%s: cannot SSL_accept(), retval: %d\n", procname, status);
}
log_printf("SSL_get_peer_certificate()");
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1, tries = 0;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
while(htmlparams == NULL || clen - strlen(htmlparams) > 0) {
log_printf("SSL_read()\n");
if((bytes = SSL_read(ssl, buffer, sizeof(buffer))) < 0) {
int errerrno, err, err2;
errerrno = errno;
err = SSL_get_error(ssl, bytes);
err2 = ERR_get_error();
log_errprintf("SSL_read()");
log_errprintf(", retval %d", bytes);
log_errprintf(", errno: %d", errerrno);
log_errprintf(", SSL_get_error(): %d", err);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
if(++tries >= 5) {
ok = 0;
break;
}
usleep(1024 * 512 / 5);
continue;
}
reads++;
if(bytes == 0)
break;
if(htmlinlen < totalbytes + bytes + 1) {
htmlinlen = totalbytes + bytes + 1;
htmlin = realloc(htmlin, htmlinlen);
}
memcpy(htmlin + totalbytes, buffer, bytes);
totalbytes += bytes;
*(htmlin + totalbytes) = '\0';
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod, &p);
if(htmlparams != NULL && !strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf("\n");
log_printf("%s\n", htmlin);
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
log_printf("SSL_write()\n");
if((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) < 1) {
log_errprintf("%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\n",
procname, c, status, SSL_get_error(ssl, status));
}
}
}
for(int c = 0; c < HTML_BUFFERS; c++) {
if(strlen(html_get_string(c)))
log_printf("%s\n", html_get_string(c));
}
}
log_printf("SSL connection using %s\n", htmlsslcipher);
log_printf("dbs_query_vars()\n");
dbs_query_vars();
log_printf("SSL_free()\n");
SSL_free(ssl);
}
static void dbs_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)
HashUpdate(&ctx, buffer, c);
fclose(fp1);
}
HashFinal(hash, &ctx);
}
unsigned char cert_digest[HashLen]; // current certificate digests
unsigned char privatekey_digest[HashLen];
static SSL_CTX *server_https_init()
{
SSL_METHOD *method = NULL;
SSL_CTX *ctx = NULL;
unsigned char cert_digest2[HashLen]; // before change
unsigned char privatekey_digest2[HashLen];
unsigned char cert_digest3[HashLen]; // after change
unsigned char privatekey_digest3[HashLen];
log_printf("SSL_library_init()\n");
SSL_library_init();
log_printf("OpenSSL_add_ssl_algorithms()\n");
OpenSSL_add_ssl_algorithms();
log_printf("OpenSSL_add_ciphers()\n");
OpenSSL_add_all_ciphers();
log_printf("OpenSSL_load_error_strings()\n");
SSL_load_error_strings();
log_printf("SSLv23_server_method()\n");
if((method = (SSL_METHOD *)
SSLv23_server_method()) == NULL) {
log_errprintf("%s: cannot SSLv3_server_method()\n", procname);
//fflush(stderr);
}
log_printf("SSL_CTX_new()\n");
if((ctx = SSL_CTX_new(method)) == NULL) {
log_errprintf("%s: cannot SSL_CTX_new()\n", procname);
}
for(;;) { // 2025 JariK
dbs_file_digest(cert_file, cert_digest2); // save before change digests
dbs_file_digest(privatekey_file, privatekey_digest2);
log_printf("SSL_CTX_use_certificate_file()\n");
if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_certificate_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
log_printf("SSL_CTX_use_PrivateKey_file()\n");
if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("%s: cannot SSL_CTX_use_PrivateKey_file()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
dbs_file_digest(cert_file, cert_digest3); // save after change digests
dbs_file_digest(privatekey_file, privatekey_digest3);
// redo if before stamps are different from after stamps
if(memcmp(cert_digest2, cert_digest3, sizeof(cert_digest3)) ||
memcmp(privatekey_digest2, privatekey_digest3, sizeof(privatekey_digest3)))
continue;
memcpy(cert_digest, cert_digest2, sizeof(cert_digest2));
memcpy(privatekey_digest, privatekey_digest2, sizeof(privatekey_digest2));
log_dump("cert", 32, cert_digest, 32); // first 32 bytes
log_dump("private", 32, privatekey_digest, 32); // first 32 bytes
break;
}
log_printf("SSL_CTX_load_verify_locations()\n");
if(SSL_CTX_load_verify_locations(ctx, cert_file, NULL) != 1) {
int err2;
err2 = ERR_get_error();
log_errprintf("\n%s: cannot SSL_CTX_load_verify_locations()", procname);
log_errprintf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_errprintf(", %d", err2);
log_errprintf("\n");
}
return(ctx);
}
static int https_keyschange_needed() // 2025 JariK
{
unsigned char cert_digest2[HashLen];
unsigned char privatekey_digest2[HashLen];
dbs_file_digest(cert_file, cert_digest2);
dbs_file_digest(privatekey_file, privatekey_digest2);
log_dump("cert", 32, cert_digest2, 32); // first 32 bytes
log_dump("private", 32, privatekey_digest2, 32); // first 32 bytes
if(memcmp(cert_digest, cert_digest2, sizeof(cert_digest2)) ||
memcmp(privatekey_digest, privatekey_digest2, sizeof(privatekey_digest2)))
return(1);
else
return(0);
}
static void https_server()
{
int quit, reset, addr_size;
struct sockaddr_in sa_cli;
SSL_CTX *ctx = NULL;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
reset = 1;
quit = 0;
for(;;) {
log_mode = 1;
if(quit) {
break;
}
if(https_keyschange_needed())
reset = 1;
if(reset) {
if(ctx != NULL) {
log_printf("SSL_CTX_free()\n");
SSL_CTX_free(ctx);
}
if(s != -1) {
log_printf("server_close()\n");
server_close(s);
}
log_printf("server_https_init()\n");
ctx = server_https_init();
log_printf("server_basic_socket()\n");
s = server_basic_socket();
reset = 0;
}
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
log_printf("accept()\n");
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
log_errprintf("%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
log_printf("========================================\n");
log_printf("dbs_time_vars()\n");
dbs_time_vars();
pid_t pid;
log_printf("fork start (parent)");
log_printf(" getpid:%d getppid:%d", getpid(), getppid());
log_printf("\n");
log_printf("fork()\n");
if((pid = fork()) < 0) {
log_errprintf("%s: cannot fork()", procname);
log_errprintf(", errno %d", errno);
log_errprintf( "(%s)\n", strerror(errno));
perror("fork");
fflush(stderr);
exit(1);
} else if(pid == 0) { // child
log_printf("init_child()\n");
init_child();
log_mode = 2; // child
log_printf("close(s)\n");
close(s);
log_printf("https_client()\n");
https_client(news, ctx, sa_cli, addr_size, "https");
dbs_run_critical_sections();
log_printf("server_close(news)\n");
server_close(news);
log_printf("fork end (child)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("exit_child()\n");
exit_child();
exit(0);
}
log_printf("fork end (parent)");
log_printf(" pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
log_printf("\n");
log_printf("server_close()\n");
server_close(news);
} // for(;;)
}
int http = 1;
int https = 0;
void main(int argc, char *argv[])
{
int c;
procname = argv[0];
//
// look thru command line parameters
//
for(c = 1; c < argc; c++) {
if(!strncmp("-", argv[c], 1)) {
if(!strncmp("--port", argv[c], 6)) {
if(*(argv[c] + 6) != '\0')
myport = argv[c] + 6;
else if(c + 1 < argc) {
myport = argv[c + 1];
c++;
}
} else if(!strcmp("--https", argv[c])) {
https = 1;
http = 0;
} else if(!strcmp("--http", argv[c])) {
http = 1;
https = 0;
} else {
log_errprintf("%s: invalid option %s\n", procname, argv[c]);
exit(1);
}
}
}
log_errprintf("starting dbs3 \"%s\"", programname);
log_errprintf(", port:%s", myport);
if(http)
log_errprintf(", http");
if(https)
log_errprintf(", https");
log_errprintf("\n");
unsigned char filedigest[HashLen];
dbs_file_digest("/proc/self/exe", filedigest);
htmldigest[0] = '\0';
for(int c = 0; c < HashLen; c++) {
char twodigits[3];
sprintf(twodigits, "%02x", filedigest[c]);
strcat(htmldigest, twodigits);
}
getcwd(homedir,sizeof(homedir));
log_printf("homedir: \"%s\"\n", homedir);
if(http)
http_server();
if(https)
https_server();
}