A B C D E F G H I
+-----------+-----------+-----------+
A | | | 3 5 |
B | 5 | | 8 |
C | 7 | 4 | |
+-----------+-----------+-----------+
D | 1 | 3 | 6 |
E | | | 5 |
F | 2 | 1 8 | |
+-----------+-----------+-----------+
G | | 9 | 1 6 |
H | 4 2 | | |
I | | 6 7 | 4 |
+-----------+-----------+-----------+
s:0 gu:0 st:0 ro:6 clues:21
Kaikki oikeudet pidätetään ©.Suomessa voi vastaanottaa lahjoituksia, mutta niitä ei voi pyytää. Jos haluat tukea projektia (osallistua palvelinkustannuksiin, tarjota koodausvissyn, uuden läppärin tai tulevaisuudessa maksaa palkkaa), laita muutaman euron lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikenttään nimesi tai nimimerkkisi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi. Suuremman kun 100€ lahjoituksen vastalahjaksi saat tulostetun, vesileimatun ja muovitetun sudokun oheisista sudokuista (kirjoita viestin loppuun ‘sudoku2026vol2’). Vaihda kakkonen haluamaasi vol numeroon. Jos haluat sudokun postitse jätä viesti jossa on nimimerkkisi, asuinpaikkakuntasi ja osoitteesi osoitteeseen moijaricom@gmail.com.
Ressu2 current source
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#include <sys/time.h>
#include <time.h>
#define MAIN
unsigned char *procname;
static unsigned char *programname = "Ressu2 version 1.00 ©";
static unsigned char *copyright = "Copyright (c) 2013-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";
int my_output = 0;
void my_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
int c;
if(my_output) {
fprintf(stdout,"\n");
my_output = 0;
}
for(c = 0; c < len; c++) {
if(c % linelen == 0) {
if(c > 0)
fprintf(stdout,"\n");
fprintf(stdout,"%-10s", header);
}
fprintf(stdout," %02x", buf[c]);
}
fprintf(stdout,"\n");
fflush(stdout);
}
#define aDEBUG8 2
#define USE_URANDOM 2
#define USE_RESSU2 2
#define USE_PSEUDORESSU2 2
#define USE_RESSU2TWIST 2
#if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST
static unsigned long long my_ressu_useconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}
static unsigned char my_ressu_lowusec() /* JariK 2013 */
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec & 0xff);
}
static int randomness = 0;
#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )
static void my_ressu2_round(int size, unsigned char *buffer) // ressu JariK 2013, 2025
{
int c, d, byte;
unsigned char e;
static int f = 0, prevbyte = -1;
unsigned long long usec;
for(c = 0; c < 8; c++) { // eight bits per byte
for(d = 0; d < size; d++) { // rotate + xor
e = buffer[d];
e = RESSU_ROTATELEFT8(e, 1); // rotate byte left 1 bits
byte = my_ressu_lowusec();
buffer[d] = e ^ byte;
if(prevbyte != byte) {
prevbyte = byte;
randomness++;
}
}
for(d = 0; d < size; d++) { // swap
f = (f + 16 + buffer[d] + 2) % size;
e = buffer[d];
buffer[d] = buffer[f];
buffer[f] = e;
}
// more randomness from clocks
usec = clock();
while(usec > 0) {
f = (f + usec) % size;
usec /= size;
}
usec = my_ressu_useconds();
while(usec > 0) {
f = (f + usec) % size;
usec /= size;
}
} // end of for(c = 0; c < 8; c++
}
#include "newressu.h"
#define RESSU2_BYTES 2048 // now 2048
#define RESSU2_RANDOMNESS_NEEDED 2048 // now 2048
#define RESSU2_CLOCKS_NEEDED 20480 // now 20480
#define RESSU2_MINIMUM_ROUNDS 5 // now 5
void my_ressu2_bytes(int size, unsigned char *buffer) // Ressu2 v1.0 JariK 2013, 2025
{
int c, d, clocksused;
static int ressu_pos = 0, initneeded = 1;
static unsigned char ressu[RESSU2_BYTES];
for(c = 0; c < size; c++) {
if(ressu_pos == 0) {
if(initneeded) {
memset(&ressu, 0, sizeof(ressu));
initneeded = 0;
}
randomness = 0;
clocksused = 0;
//memset(&ressu, 0, sizeof(ressu));
for(d = 0; d < RESSU2_MINIMUM_ROUNDS ||
randomness < RESSU2_RANDOMNESS_NEEDED ||
clocksused < RESSU2_CLOCKS_NEEDED
; d++) {
my_ressu2_round(sizeof(ressu), ressu);
clocksused += (sizeof(ressu) * 8);
}
#ifdef DEBUG8
my_dump("myressu2g", sizeof(ressu), ressu, 32);
#endif
} // end of if(ressu_pos == 0
buffer[c] ^= ressu[ressu_pos];
ressu_pos = (ressu_pos + 1) % sizeof(ressu);
} // end of for(c = 0; c < size; c++
#ifdef DEBUG8
my_dump("myressu2", size, buffer, 32);
#endif
}
#endif // end of #if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST
#if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST
unsigned char cvar[16];
int cvarsize = 0;
void inccvar()
{
int c;
/* 16 bytes, LSB first */
for(c = 0; ++cvar[c] == 0 && c < sizeof(cvar) - 1; c++);
if(cvarsize < c)
cvarsize = c;
#ifdef DEBUG20
ressu_dump("cvar", cvarsize + 1, cvar, 32);
#endif
}
void clearcvar()
{
int c;
cvarsize = 0;
for(c = 0; c < sizeof(cvar); c++)
cvar[c] = 0;
for(c = 0; c < sizeof(cvar); c++)
if(cvar[c] != 0)
cvarsize = c;
}
#include "sha256.h"
#define PSEUDORESSU2_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define PSEUDORESSU2_TOPUP_TWICE 2 // off by default
static unsigned char pseudoressu2_key[HashLen]; // 32 bytes, 256 bits
static void my_pseudoressu2_internalbytes(unsigned char *digest)
{
HashCtx hash;
HashInit(&hash);
HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
inccvar();
HashFinal(digest, &hash);
memset(&hash, 0, sizeof(hash)); // forget hash
}
static void my_pseudoressu2_addrandomness(int size, unsigned char *buffer)
{
unsigned long long usec;
HashCtx hash;
HashInit(&hash);
HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
inccvar();
usec = my_ressu_useconds(); // add timestamp to hash
HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
usec = clock(); // add processor time to hash (for randomness)
HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
HashUpdate(&hash, buffer, size); // add given randomness to hash
HashFinal(pseudoressu2_key, &hash); // save as new key
memset(&hash, 0, sizeof(hash)); // forget hash
}
static void my_pseudoressu2_topup()
{
unsigned char topup[PSEUDORESSU2_TOPUP_SIZE]; // 32 bytes, 256 bits
memset(&topup, 0, sizeof(topup)); // forget topup
my_ressu2_bytes(sizeof(topup), topup);
#ifdef DEBUG8
my_dump("topup", sizeof(topup), topup, 32);
#endif
my_pseudoressu2_addrandomness(sizeof(topup), topup);
memset(&topup, 0, sizeof(topup)); // forget topup
}
void my_pseudoressu2_bytes(int size, unsigned char *buffer) // JariK 2022, 2025
{
int c;
static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits
for(c = 0; c < size; c++) {
if(pseudoressu_pos == 0) {
if(topup_counter == 0) {
if(initneeded) {
my_ressu2_bytes(sizeof(pseudoressu2_key), pseudoressu2_key); // get first key
#ifdef DEBUG8
my_dump("first key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
initneeded = 0;
} // end of if(initneeded
my_pseudoressu2_topup(); // add randomness to key, first block also
#ifdef PSEUDORESSU2_TOPUP_TWICE
my_pseudoressu2_topup(); // add randomness to key, first block also
#endif
topup_counter = PSEUDORESSU2_TOPUP_BYTES;
} // end of if(topup_counter == 0
my_pseudoressu2_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
my_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
topup_counter -= sizeof(pseudoressu);
} // end of if(pseudoressu_pos == 0
buffer[c] ^= pseudoressu[pseudoressu_pos];
pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
} // end of for(c = 0; c < size; c++
my_pseudoressu2_internalbytes(pseudoressu2_key); // replace key with new random one
#ifdef DEBUG8
my_dump("new key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
#ifdef DEBUG8
my_dump("pseudoressu", size, buffer, 32);
#endif
}
#endif // end of #if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST
#ifdef USE_RESSU2TWIST
void my_ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023, 2025
{
//urandom_bytes(size, buffer);
my_ressu2_bytes(size, buffer);
my_pseudoressu2_bytes(size, buffer);
#ifdef DEBUG8
my_dump("ressu2twist", size, buffer, 32);
#endif
}
#endif // end of #ifdef USE_RESSU2TWIST
#ifdef USE_URANDOM
void my_readfile_xor(int size, unsigned char *buffer, unsigned char *filename)
{
int c, n, filebuffer_pos = 0;
unsigned char filebuffer[64];
FILE *fp1;
if((fp1 = fopen(filename, "rb")) == NULL) {
fprintf(stderr,"%s: fopen(): cannot open file %s\n",
procname, filename);
exit(1);
}
for(c = 0; c < size; c++) {
if(filebuffer_pos == 0) {
n = (size - c < sizeof(filebuffer)) ? size - c : sizeof(filebuffer);
if(fread(filebuffer, 1, n, fp1) < n) {
fprintf(stderr,"%s: fread(): cannot read file %s\n",
procname, filename);
exit(1);
}
#ifdef DEBUG8
my_dump("file", n, filebuffer, 32);
#endif
} // end of if(file_pos == 0
buffer[c] ^= filebuffer[filebuffer_pos];
filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);
} // end of for(c = 0; c < size; c++
fclose(fp1);
memset(filebuffer, 0, sizeof(filebuffer)); // forget file
}
static unsigned char urandomfilename[128] = "/dev/urandom";
void my_urandom_bytes(int size, unsigned char *buffer)
{
my_readfile_xor(size, buffer, urandomfilename);
#ifdef DEBUG8
my_dump("urandom", size, buffer, 32);
#endif
}
#endif // end of #ifdef USE_URANDOM
void my_random_bytes(int size, unsigned char *buffer)
{
#ifdef USE_URANDOM
my_urandom_bytes(size, buffer);
#endif
//ressu_round(size, buffer);
//ressu_genbytes(size, buffer);
//pseudoressu_bytes(size, buffer);
//ressutwist_bytes(size, buffer);
//my_ressu2_round(size, buffer);
#ifdef USE_PSEUDORESSU2
my_pseudoressu2_bytes(size, buffer);
#endif
#ifdef USE_RESSU2TWIST
my_ressu2twist_bytes(size, buffer);
#endif
#ifdef USE_RESSU2
my_ressu2_bytes(size, buffer);
#endif
}
#define GENT_SIZE 128
static unsigned char gent[GENT_SIZE];
static unsigned int gent_pos = 0;
int my_random_byte()
{
unsigned char ch;
static int initneeded = 1;
if(gent_pos == 0) {
if(initneeded) {
memset(&gent, 0, sizeof(gent));
initneeded = 0;
}
my_random_bytes(sizeof(gent), gent);
}
ch = gent[gent_pos];
gent_pos = (gent_pos + 1) % sizeof(gent);
return(ch);
}
unsigned long my_random_genlimit(unsigned long limit)
{
int c;
unsigned long word;
static unsigned long lastlimit = 0, highlimit;
static int bytes;
if(lastlimit != limit) { // if limit changes, calculate new highlimit and bytes
lastlimit = limit;
if(limit <= 0x100) {
// highest multiplier of limit that fits to needed bytes
highlimit = (0x100 / limit) * limit;
// number of bytes needed
bytes = 1;
} else if(limit <= 0x10000) {
highlimit = (0x10000 / limit) * limit;
bytes = 2;
} else if(limit <= 0x1000000) {
highlimit = (0x1000000 / limit) * limit;
bytes = 3;
} else if(limit <= 0x100000000) {
highlimit = (0x100000000 / limit) * limit;
bytes = 4;
} else if(limit <= 0x10000000000) {
highlimit = (0x10000000000 / limit) * limit;
bytes = 5;
} else if(limit <= 0x1000000000000) {
highlimit = (0x1000000000000 / limit) * limit;
bytes = 6;
} else if(limit <= 0x100000000000000) {
highlimit = (0x100000000000000 / limit) * limit;
bytes = 7;
} else { // if(limit <= 0xffffffffffffffff) {
highlimit = (0xffffffffffffffff / limit) * limit;
bytes = 8;
}
} // if(lastlimit != limit)
for(;;) {
word = 0;
for(c = 0; c < bytes; c++)
word = word << 8 | my_random_byte();
if(word < highlimit)
break;
}
word %= limit;
return(word);
}
void ressu2_version()
{
fprintf(stderr, "%s", programname); // touch these outside #ifdef MAIN
fprintf(stderr, ", %s", copyright);
}
#include <sys/ioctl.h> // for TIOCGWINSZ
#ifdef MAIN
int main(int argc, char *argv[])
{
int c, d;
int space = 1;
int chars = 0;
int columns = 0;
int lines = 0;
int words = 16;
int wordlength = 2;
int screen = 0;
int lim = 256;
procname = argv[0];
int clines, ccolumns;
//print hello world line
#define DEBUG76 2
#ifdef DEBUG76
fprintf(stdout,"Hello world");
// fprintf(stdout,"Hello world\n");
for(clines = 0; clines < 10; clines++) {
fprintf(stdout, "%05x", clines);
my_output = 1;
for(ccolumns = 0; ccolumns < 32; ccolumns++) {
fprintf(stdout, " ");
fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
}
//fprintf(stdout,"\n");
fprintf(stdout," ");
}
#endif // end of #ifdef DEBUG76
//
// look thru command line parameters
//
for(c = 1; c < argc; c++) {
if(!strcmp("--copyright", argv[c]) ||
!strcmp("--version", argv[c])) {
ressu2_version();
#ifdef SHA256
fprintf(stderr,"\nsha256(");
for(int c = 0; c < HashLen; c++) {
fprintf(stderr, "%02x", programfiledigest[c]);
}
#endif // end of #ifdef SHA256
} else if(!strcmp("-c*", argv[c])) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
words = 0;
} else if(!strcmp("-l*", argv[c])) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
lines = w.ws_row-1;
} else if(!strncmp("--chars*", argv[c], 8)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
words = 0;
} else if(!strncmp("--lines*", argv[c], 8)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
lines = w.ws_row-1;
} else if(!strncmp("--lim", argv[c], 5)) {
if(isdigit(*(argv[c] + 7))) {
lim = atoi(argv[c] + 7);
} else if(c + 1 < argc) {
lim = atoi(argv[c + 1]);
c++;
}
} else if(!strncmp("--screen", argv[c], 8)) { // screenful
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
lines = w.ws_row-1;
words = 0;
screen = 1;
} else if(!strncmp("--chars", argv[c], 7)) { // characters per line
if(isdigit(*(argv[c] + 7))) {
chars = atoi(argv[c] + 7);
} else if(c + 1 < argc) {
chars = atoi(argv[c + 1]);
c++;
}
if(chars < 1)
chars = 72;
words = 0;
screen = 0;
} else if(!strncmp("-c", argv[c], 2)) { // characters per line
if(isdigit(*(argv[c] + 2))) {
chars = atoi(argv[c] + 2);
} else if(c + 1 < argc) {
chars = atoi(argv[c + 1]);
c++;
}
if(chars < 1)
chars = 72;
words = 0;
screen = 0;
columns = 0;
} else if(!strncmp("--lines",argv[c], 7)) { // lines
if(isdigit(*(argv[c] + 7))) {
lines = atoll(argv[c] + 7);
} else if(c + 1 < argc) {
lines = atoll(argv[c + 1]);
c++;
}
screen = 0;
} else if(!strncmp("--words",argv[c], 7)) { // lines
if(isdigit(*(argv[c] + 7))) {
words = atoll(argv[c] + 7);
} else if(c + 1 < argc) {
words = atoll(argv[c + 1]);
c++;
}
screen = 0;
} else if(!strncmp("--space",argv[c], 7)) { // lines
if(isdigit(*(argv[c] + 7))) {
space = !space;
}
screen = 0;
} else if(!strncmp("-l",argv[c], 2)) { // lines
if(isdigit(*(argv[c] + 2))) {
lines = atoll(argv[c] + 2);
} else if(c + 1 < argc) {
lines = atoll(argv[c + 1]);
c++;
}
screen = 0;
}
} //end of for(c = 1; c < argc; c++)
#define aTESTING 2
#ifdef TESTING
unsigned char columnsstring[32];
sprintf(columnsstring, "%05d", lines + 1);
fprintf(stdout,"Hello world!\n");
if(lim == 0)
lim = 256;
if(columns == 0)
columns = 16;
if(lines == 0)
lines = 10;
if(words == 0) {
words = 16;
chars = words * (space + wordlength);
}
for(clines = 0; clines < lines; clines++) {
fprintf(stdout, "%0*lld", 2, (unsigned long long) clines);
//fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
my_output = 1;
columns = strlen(columnsstring);
for(ccolumns = 0; ccolumns < columns; ccolumns++) {
if(space == 1)
fprintf(stdout, " ");
wordlength = lim;
fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
fprintf(stdout, "%0*llx", (int) wordlength, (unsigned long long) my_random_genlimit(lim));
}
fprintf(stdout, "\n");
}
#endif // testing()
return(0);
}
#endif // end of #ifdef MAIN