mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Files

Having stated the principle in the previous commit, I should apply it consistently. A source file linked into the Puzzles library of common support code should not also define a main() under ifdef. This commit only goes as far as the _library_ support modules. It would be a much bigger job to do the same for all the actual _puzzles_ that have test main()s or standalone-solver main()s. And it's not necessary, because modifying one of those source files only triggers a rebuild of _one_ puzzle, not absolutely everything. (Not to mention that it's quite likely the puzzle and the test main() will need to be modified in conjunction anyway.) As in the previous commit, this has required exposing a few internal API functions as global, and maybe editing them a bit. In particular, the one-shot internal function that divvy_rectangle() loops on until it succeeds is now exposed as divvy_rectangle_attempt(), which means the test program doesn't have to condition a failure counter into the real function. I've thrown away penrose-vector-test completely, because that didn't look like a test program with any ongoing use at all - it was surely vestigial, while James was getting the vector representation up and running in the first place.
131 lines
3.0 KiB
C
131 lines
3.0 KiB
C
/*
|
|
* Stand-alone tool to access the Puzzles obfuscation algorithm.
|
|
*
|
|
* To deobfuscate, use "obfusc -d":
|
|
*
|
|
* obfusc -d reads binary data from stdin, writes to stdout
|
|
* obfusc -d <hex string> works on the given hex string instead of stdin
|
|
* obfusc -d -h writes a hex string instead of binary to stdout
|
|
*
|
|
* To obfuscate, "obfusc -e":
|
|
*
|
|
* obfusc -e reads binary from stdin, writes hex to stdout
|
|
* obfusc -e <hex string> works on the given hex string instead of stdin
|
|
* obfusc -e -b writes binary instead of text to stdout
|
|
*
|
|
* The default output format is hex for -e and binary for -d
|
|
* because that's the way obfuscation is generally used in
|
|
* Puzzles. Either of -b and -h can always be specified to set it
|
|
* explicitly.
|
|
*
|
|
* Data read from standard input is assumed always to be binary;
|
|
* data provided on the command line is taken to be hex.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "puzzles.h"
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
enum { BINARY, DEFAULT, HEX } outputmode = DEFAULT;
|
|
char *inhex = NULL;
|
|
unsigned char *data;
|
|
int datalen;
|
|
enum { UNKNOWN, DECODE, ENCODE } mode = UNKNOWN;
|
|
bool doing_opts = true;
|
|
|
|
while (--argc > 0) {
|
|
char *p = *++argv;
|
|
|
|
if (doing_opts && *p == '-') {
|
|
if (!strcmp(p, "--")) {
|
|
doing_opts = 0;
|
|
continue;
|
|
}
|
|
p++;
|
|
while (*p) {
|
|
switch (*p) {
|
|
case 'e':
|
|
mode = ENCODE;
|
|
break;
|
|
case 'd':
|
|
mode = DECODE;
|
|
break;
|
|
case 'b':
|
|
outputmode = BINARY;
|
|
break;
|
|
case 'h':
|
|
outputmode = HEX;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "obfusc: unrecognised option '-%c'\n",
|
|
*p);
|
|
return 1;
|
|
}
|
|
p++;
|
|
}
|
|
} else {
|
|
if (!inhex) {
|
|
inhex = p;
|
|
} else {
|
|
fprintf(stderr, "obfusc: expected at most one argument\n");
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mode == UNKNOWN) {
|
|
fprintf(stderr, "usage: obfusc < -e | -d > [ -b | -h ] [hex data]\n");
|
|
return 0;
|
|
}
|
|
|
|
if (outputmode == DEFAULT)
|
|
outputmode = (mode == DECODE ? BINARY : HEX);
|
|
|
|
if (inhex) {
|
|
datalen = strlen(inhex) / 2;
|
|
data = hex2bin(inhex, datalen);
|
|
} else {
|
|
int datasize = 4096;
|
|
datalen = 0;
|
|
data = snewn(datasize, unsigned char);
|
|
while (1) {
|
|
int ret = fread(data + datalen, 1, datasize - datalen, stdin);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "obfusc: read: %s\n", strerror(errno));
|
|
return 1;
|
|
} else if (ret == 0) {
|
|
break;
|
|
} else {
|
|
datalen += ret;
|
|
if (datasize - datalen < 4096) {
|
|
datasize = datalen * 5 / 4 + 4096;
|
|
data = sresize(data, datasize, unsigned char);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
obfuscate_bitmap(data, datalen * 8, mode == DECODE);
|
|
|
|
if (outputmode == BINARY) {
|
|
int ret = fwrite(data, 1, datalen, stdout);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "obfusc: write: %s\n", strerror(errno));
|
|
return 1;
|
|
}
|
|
} else {
|
|
int i;
|
|
for (i = 0; i < datalen; i++)
|
|
printf("%02x", data[i]);
|
|
printf("\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|