Skip to content

Instantly share code, notes, and snippets.

@toke
Last active July 3, 2020 00:36
Show Gist options
  • Save toke/bc0c6780cfb5df12d03d to your computer and use it in GitHub Desktop.
Save toke/bc0c6780cfb5df12d03d to your computer and use it in GitHub Desktop.
K.R.A.U.S. in C

K.R.A.U.S. in pure C

Abstract

This is a C fork of the famous K.R.A.U.S. (floor of the day) application by @jautz written in perl. The acronym K.R.A.U.S. stands for the German phrase "Kaffee-Runde auf unterschiedlichen Stockwerken". It's origin lies far in the beginning of civilisation and was once called Tempus clausum.

Since being independent of a single implementation is cruical for live threatening services this fork has been established.

Usage

kraus [delta] [count]

List K.R.A.U.S. floor for current date + delta for count days. delta and count are optional. If no arguments are given the floor of the current day is printed on stdout.

Example

kraus 0 10 will print the floor of today and the next 9 days.

Implementation

Based on reverse engeneering the perl 5.6 srand() and rand() random number generators which are basically calling the (System V/POSIX) random number generator seed48() and drand48() Pseudorandom Functions (at least in our use case).

This is how perl initializes the seed value (in our case):

unsigned short seed[3] = {0x330e,perl_seed[0],perl_seed[1]};

According to man drand48 (3) seed48 generates:

…a sequence of 48-bit integers, Xi, according to the linear congruential formula: Xn+1 = (aXn + c) mod m, where n >= 0 The parameter m = 2^48, hence 48-bit integer arithmetic is performed.

While drand48:

The drand48() and erand48() functions return nonnegative double- precision floating-point values uniformly distributed between [0.0, 1.0)

Installation

Dependencies: none

Build with:

gcc -o kraus kraus.c

Bugs

  • This code is not multi-threading safe
  • We have different time based problems. (Thanks John Titor for pointing this out) One of course obvious and final one is the end of our universe. The code does not cope with this event and users should be aware of possible side effects. [CITATION NEEDED]

Notes

The original author of K.R.A.U.S @jautz has used perl as it's language of choice (for very noble reasons). I read the motto of perl in a different way. "There's more than one way to do it." I saw this as my challenge.

Fun fact: the resulting code is just slightly smaller than the complete list of all possible values. The compiled version is larger. But sssshhh this has to kept a secret.

Pro Tip: The command kraus 0 365 | awk -- '{ print $2 "\tKRAUS " $8 }' > calendar will generate a file that you be fed to the linux calendar program.

References

/*
* ----------------------------------------------------------------------------
* "THE COFFEE-WARE LICENSE" (Revision 23):
* <toke@toke.de> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can bring me a coffee in return.
* ----------------------------------------------------------------------------
*/
#include "kraus.h"
int main(int argc, char *argv[])
{
time_t current_time;
struct tm *kd;
int deltad = 0; // delta in days from current day
unsigned int count = 1; // number of results
int i;
kraus_t floor;
// Optional handling of arguments (delta days and count)
if (argc > 1) {
deltad = atoi(argv[1]);
if (argc > 2) {
count = atoi(argv[2]);
}
}
time(&current_time);
current_time += deltad;
for (i=0; i < count; i++) {
kd = localtime(&current_time);
kd->tm_mday += deltad + i;
mktime(kd);
floor = kraus_floor(kd);
(void) printf("Am %02i.%02i treffen wir uns in Stockwerk %i\n",
kd->tm_mday, kd->tm_mon + 1, floor);
}
return 0;
}
kraus_t kraus_floor(struct tm *date)
{
unsigned short perl_seed[2] = {0};
double rand_number = 0;
kraus_t floor;
// The S.U.P.E.R. secret Algorithm (Part 1)
perl_seed[0] = (date->tm_mday * date->tm_mday + date->tm_mon + 1);
// Seed like perl 5.6 does
unsigned short seed[3] = {SEEDMAGIC, perl_seed[0], perl_seed[1]};
seed48(&seed[0]);
rand_number = drand48();
// The S.U.P.E.R. secret Algorithm (Part 2)
floor = (rand_number * MAX_FLOOR) + MIN_FLOOR;
return floor;
}
#ifndef _KRAUS_H_
#define _KRAUS_H_
/*
* ----------------------------------------------------------------------------
* "THE COFFEE-WARE LICENSE" (Revision 23):
* <toke@toke.de> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can bring me a coffee in return.
* ----------------------------------------------------------------------------
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#define MIN_FLOOR 1
#define MAX_FLOOR 8
#define SEEDMAGIC 0x330e
typedef unsigned int kraus_t;
kraus_t kraus_floor(struct tm *date);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment