Skip to content

Instantly share code, notes, and snippets.

@foxcpp
Created June 11, 2020 15:21
Show Gist options
  • Save foxcpp/0c7e52434e7fccde3a3cb1fcf518cce5 to your computer and use it in GitHub Desktop.
Save foxcpp/0c7e52434e7fccde3a3cb1fcf518cce5 to your computer and use it in GitHub Desktop.
High-performance stdin bitflip'er
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>
typedef union rnd_state_t {
uint64_t s64;
uint32_t s32[2];
uint16_t s16[4];
uint8_t s8[8];
} rnd_state_t;
static void xorshift64(uint64_t *s) {
*s ^= *s << 21;
*s ^= *s >> 15;
*s ^= *s << 29;
}
static uint16_t rnd16(rnd_state_t *state) {
xorshift64(&state->s64);
return state->s16[0];
}
static uint8_t* generate_table(double prob, size_t size) {
uint8_t* buf = malloc(sizeof(double)*size);
assert(buf != NULL);
for (size_t i = 0; i < size; ++i) {
uint8_t ent = 0;
for (int j = 0; j < 8; ++j) {
if (rand() < (RAND_MAX * prob)) {
ent |= 1 << j;
}
}
buf[i] = ent;
}
return buf;
}
const double probability = 0.5;
const size_t tbl_size = 65535;
int main(void) {
srand(time(NULL));
uint8_t* tbl = generate_table(probability, tbl_size);
rnd_state_t state;
state.s64 = clock();
const size_t buffer_size = 4096;
uint8_t* buffer = malloc(buffer_size);
size_t tick = 0;
size_t consumed = 0;
while ((consumed = fread(buffer, sizeof(uint8_t), buffer_size, stdin)) > 0) {
for (size_t i = 0; i < consumed; ++i) {
buffer[i] ^= tbl[rnd16(&state) % tbl_size];
}
fwrite(buffer, sizeof(uint8_t), consumed, stdout);
if (++tick % 255 == 0) {
free(tbl);
tbl = generate_table(probability, tbl_size);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment