#include <stdint.h>

static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;

static uint32_t xorshift128(void) {
  uint32_t t = x;
  t ^= t << 11;
  t ^= t >> 8;
  x = y; y = z; z = w;
  w ^= w >> 19;
  w ^= t;
  return w;
}

uint32_t prand(void) {
  return xorshift128();
}

void psrand(uint32_t seed) {
  if (seed == 0) seed = 1;

  x = seed;
  y = seed ^ 0xDEADBEEF;
  z = seed ^ 0xCAFEBABE;
  w = seed ^ 0xF00DCAFE;

  for (int i = 0; i < 10; i++) xorshift128();
}

uint32_t genseed(void) {
  uint32_t seed = 0;
  seed ^= (uint32_t)(uintptr_t)&seed;

  uint32_t uninit_var;
  seed ^= uninit_var;

  volatile uint32_t counter = 0;
  for (int i = 0; i < 1000; i++) counter += i;

  seed ^= counter;
  seed ^= (uint32_t)__LINE__ ^ (uint32_t)(uintptr_t)__FILE__;

  x = seed;
  y = seed ^ 0xDEADBEEF;
  z = seed ^ 0xCAFEBABE;
  w = seed ^ 0xF00DCAFE;
  seed = xorshift128();

  if (seed == 0) seed = 1;
  return seed;
}

void uint_to_string(uint32_t num, char *buf, int *len) {
  char tmp[11];
  int i = 0;
  if (num == 0) {
    buf[0] = '0';
    buf[1] = '\0';
    *len = 1;
    return;
  }

  while (num > 0) {
    tmp[i++] = (num % 10) + '0';
    num /= 10;
  }

  *len = i;
  for (int j = 0; j < i; j++) buf[j] = tmp[i - 1 - j];

  buf[i] = '\0';
}

static inline long syscall(long arg1, long arg2, long arg3) {
#if defined(__linux__)
  long num = 1;
  long ret;
  register long rdi asm("rdi") = arg1; // ファイルディスクリプタ
  register long rsi asm("rsi") = arg2; // バッファー
  register long rdx asm("rdx") = arg3; // 長さ
  register long rax asm("rax") = num; // システムコール:書き込み
  __asm__ volatile ("syscall"
    : "=a"(ret)
    : "r"(num), "r"(arg1), "r"(arg2), "r"(arg3)
    : "rdi", "rsi", "rdx", "rcx", "r11", "memory");

  return ret;
#elif defined(__FreeBSD__)
  long num = 4;
  long ret;
  __asm__ volatile (
    "mov %1, %%rax\n"
    "mov %2, %%rdi\n"
    "mov %3, %%rsi\n"
    "mov %4, %%rdx\n"
    "syscall\n"
    : "=a"(ret)
    : "r"(num), "r"(arg1), "r"(arg2), "r"(arg3)
    : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r10", "r11", "memory", "cc"
  );
  return ret;
#else
  return 0;
#endif
}

int main(void) {
  psrand(genseed());

  char buf[32];
  int blen;
  int min = 0x01, max = 0xFF;
  int random = min + (prand() % (max - min + 1));

  uint_to_string(random, buf, &blen);
  syscall(1, (long)buf, blen);
  syscall(1, (long)"\n", 1);

  return 0;
}