Skip to content

Instantly share code, notes, and snippets.

@fjolnir
Created April 23, 2012 13:38
Show Gist options
  • Save fjolnir/2470981 to your computer and use it in GitHub Desktop.
Save fjolnir/2470981 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#define MAX(x,m) ((x)>(m) ? (x) : (m))
int bin2dec(char *str, int len) {
int ret = 0, i;
for(i=0; i < len; ++i)
ret += (str[i] - '0') * pow(2, len-i-1);
return ret;
}
int str2idx(char *str, int len) {
int ret = bin2dec(str, len), i;
char ones[len-1];
memset(ones, '1', len-1);
for(i = 1; i < len; ++i)
ret += bin2dec(ones, i);
return ret;
}
void decodeTransmission(char *transmission, char *output, size_t outLen)
{
char *msg = NULL;
for(msg = transmission; *msg != '\0'; ++msg) {
if(*msg >= '0' && *msg <= '1')
break;
}
assert(msg != NULL);
int headerLen = msg - transmission;
assert(headerLen > 0);
char header[headerLen];
memcpy(header, transmission, headerLen);
int msgLen = strlen(msg);
char *end = msg+msgLen-4;
assert(strncmp(end, "000\n", 4) == 0);
int keyCount = (-1 + sqrt(1 + 8*msgLen))/2.0;
char result[keyCount];
memset(result, '\0', keyCount);
int maxKeyLen = MAX(3, keyCount);
char keyBuf[maxKeyLen];
memset(keyBuf, 0, maxKeyLen);
int keyLen = 3;
char terminator[maxKeyLen];
memset(terminator, '1', maxKeyLen);
int keyCursor = 0, resultCursor = 0;
bool counting = true;
for(; msg < end; ++msg) {
if(*msg == '\r') continue;
keyBuf[keyCursor] = *msg;
if(++keyCursor != keyLen) continue;
keyCursor = 0;
int dec = bin2dec(keyBuf, keyLen);
if(counting) {
keyLen = dec;
counting = false;
} else if(strncmp(keyBuf, terminator, keyLen) == 0) {
counting = true;
keyLen = 3;
} else
result[resultCursor++] = header[str2idx(keyBuf, keyLen)];
}
if(output)
strncpy(output, result, outLen);
}
int main(int argc, char *argv[]) {
FILE *input = fopen(argv[1], "r");
char transmission[1024];
char result[1024];
while(fgets(transmission, 1024, input)) {
if(transmission[0] == '\n') continue;
decodeTransmission(transmission, result, 1024);
puts(result);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment