Last active
October 16, 2018 03:25
-
-
Save Muffindrake/0a126f10f30757d23715d85a2ccda8d5 to your computer and use it in GitHub Desktop.
wormart (openssh)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <limits.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
/* prints a random art for a string, which must be given as first argument to | |
* the compiled program */ | |
/* dimensions of the random art can be specified in the form 27x9 in the | |
* environment variable WORMART_DIMENSION and must be at least 5 in either | |
* case */ | |
/* compile with: | |
* cc -Wall -Wextra -Wpedantic -std=c11 -O3 -march=native -o worm worm.c | |
* */ | |
/* writes a random art, which uses the same algorithm as used in openssh, | |
* except this implementation doesn't mark start and end points */ | |
/* the space pointed to by buf must be at least (dim_x * dim_y + 1) in size and | |
* will be null-terminated by this function */ | |
/* specified dimensions must be at least 5 in either direction */ | |
/* returns 0 on critical failure and returns a pointer to the terminating null | |
* character of the worm art otherwise */ | |
char * | |
wormart(const void *dgst, size_t sz, char *buf, size_t dim_x, size_t dim_y, | |
const char *aug) | |
{ | |
const unsigned char *val; | |
unsigned char *dirt; | |
size_t aug_max_index; | |
size_t i; | |
size_t x; | |
size_t y; | |
unsigned char tmp; | |
if (dim_x < 5 || dim_y < 5) | |
return 0; | |
if (!aug) | |
aug = " .o+=*BOX@%&#/^"; | |
aug_max_index = strlen(aug); | |
if (!aug_max_index) | |
return 0; | |
aug_max_index--; | |
if (aug_max_index > UCHAR_MAX) | |
aug_max_index = UCHAR_MAX; | |
dirt = (unsigned char *) buf; | |
memset(dirt, 0, dim_x * dim_y + 1); | |
val = dgst; | |
x = dim_x / 2; | |
y = dim_y / 2; | |
for (i = 0; i < sz; i++) { | |
tmp = val[i]; | |
for (unsigned char b = 0; b < 4; b++) { | |
if (tmp & 1) { | |
if (x < dim_x - 1) | |
x++; | |
} else { | |
if (x > 0) | |
x--; | |
} | |
if (tmp & 2) { | |
if (y < dim_y - 1) | |
y++; | |
} else { | |
if (y > 0) | |
y--; | |
} | |
if (dirt[y * dim_x + x] < aug_max_index) | |
dirt[y * dim_x + x]++; | |
tmp >>= 2; | |
} | |
} | |
for (y = 0; y < dim_y ; y++) | |
for (x = 0; x < dim_x; x++) | |
*buf++ = dirt[y * dim_x + x][aug]; | |
return buf; | |
} | |
int | |
main(int argc, char **argv) | |
{ | |
const char *env_dim; | |
const char *env_aug; | |
char *buf; | |
char *buf_end; | |
size_t i; | |
size_t dim_x; | |
size_t dim_y; | |
int ret; | |
if (argc != 2) | |
return 1; | |
env_dim = getenv("WORMART_DIMENSION"); | |
if (!env_dim) { | |
dim_x = 21; | |
dim_y = 21; | |
} else { | |
ret = sscanf(env_dim, "%zux%zu", &dim_x, &dim_y); | |
if (ret != 2) | |
return 1; | |
} | |
env_aug = getenv("WORMART_AUGMENTATION"); | |
if (!env_aug) | |
env_aug = ".^D&@C#I$X*([{"; | |
if (dim_y > (SIZE_MAX - 1) / dim_x) | |
return 1; | |
buf = malloc(dim_y * dim_x + 1); | |
if (!buf) | |
return 1; | |
buf_end = wormart(argv[1], strlen(argv[1]), buf, dim_x, dim_y, env_aug); | |
if (!buf_end) | |
return 0; | |
for (i = 0; i < dim_y; i++) | |
printf("%.*s\n", (int) dim_x, buf + i * dim_y); | |
puts(""); | |
free(buf); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment