A text-to-Brainfuck/RNA converter in ANSI C99

Brainfuck encoder

The following small ANSI C99 program reads a String from stdin and prints out a Brainfuck program that prints the same String on stdout.

Compile using gcc -o bf bf.c

Use it like this:

cat my.txt | ./bf > my.bf

Source code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    unsigned char c;
    unsigned char curval = 0;
    //Initialize reg+1 with 8
    while(1) {
        c = getchar();
        if(feof(stdin)) {break;}
        while(curval != c) {
            if(curval < c) {
                putchar('+');
                curval++;
            } else if(curval > c) {
                putchar('-');
                curval--;
            }
        }
        putchar('.');
    }
}

How does it work?

Basically it uses just one of the registers of the Brainfuck Turing machine and incremets or decrements the register to be able to print out the next byte. It doesn’t use any of the more ‘advanced’ features in Brainfuck like loops.

Brainfuck decoder

unbf is the corresponding decoder for bf – a simple brainfuck converter that interprets only the +, - and . instructions. No other instructions are interpreted.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    char c;
    char curval = 0;
    //Initialize reg+1 with 8
    while(1) {
        c = getchar();
        if(feof(stdin)) {break;}
        if(c == '+') {
            curval++;
        } else if(c == '-') {
            curval--;
        } else if(c == '.') {
            putchar(curval);
        }
    }
}

If you pipe the output of bf into unbf, the output of unbf is equal to the input to bf, in other words:

cat my.txt | ./bf | ./unbf

is equivalent to

cat my.txt

RNA encoder

RNA is a not-very-well-known esoteric language listed at the esolangs.org wiki. There also is a reference implementation for this language.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
 * This is a text-to-RNA [0] converter
 * It reads a bytestream from stdin and produces RNA code
 * that prints the bytestream read from stdin when fed
 * into the interpreter at [1].
 * 
 * References:
 * [0]: http://esolangs.org/wiki/RNA
 * [1]: http://esolangs.org/wiki/RNA/rna.c
 */

/**
 * Returns a random one of A,U,G and C
 */
char randomNucleotide(void) {
    int rnd = rand() % 4;
    if(rnd == 0) {return 'A';}
    if(rnd == 1) {return 'U';}
    if(rnd == 2) {return 'G';}
    if(rnd == 3) {return 'C';}
}

//*ptr=*ptr==memory[strg]?1:0
void printGlutamicAcid() {
    if(rand() % 2 == 0) {printf("GAA");}else{printf("GAG");}
}

//strg=*ptr
void printAlanine() {
    int rnd = rand() % 4;
        if(rnd == 0) {printf("GCA");}
        if(rnd == 1) {printf("GCC");}
        if(rnd == 2) {printf("GCG");}
        if(rnd == 3) {printf("GCU");}
}

//ptr=&memory[strg]
void printThreonine() {
    int rnd = rand() % 4;
        if(rnd == 0) {printf("ACA");}
        if(rnd == 1) {printf("ACC");}
        if(rnd == 2) {printf("ACG");}
        if(rnd == 3) {printf("ACU");}
}

//*ptr+=memory[strg]
void printArginine() {
    int rnd = rand() % 6;
        if(rnd == 0) {printf("AGA");}
        if(rnd == 1) {printf("AGG");}
        if(rnd == 2) {printf("CGA");}
        if(rnd == 3) {printf("CGC");}
    if(rnd == 4) {printf("CGG");}
    if(rnd == 5) {printf("CGU");}
}

void printGlutamine() {
    int rnd = rand() % 2;
        if(rnd == 0) {printf("CAA");}
        if(rnd == 1) {printf("CAG");}

}

void printTryptophan() {
    printf("UGG");
}

void printLeucine() {
    int rnd = rand() % 4;
        if(rnd == 0) {printf("CUA");}
        if(rnd == 1) {printf("CUC");}
        if(rnd == 2) {printf("CUG");}
        if(rnd == 3) {printf("CUU");}
}

void printTerminator() {
    int rnd = rand() % 3;
        if(rnd == 0) {printf("UAA");}
        if(rnd == 1) {printf("UAG");}
        if(rnd == 2) {printf("UGA");}
}

int main(int argc, char** argv) {
    unsigned char c;
    char* codon = (char*)malloc(3*sizeof(char)); //To generate a random codon for before and after the "gene"
    srand(time(0));
    int codonsBefore = rand() % 1000;
    int i;
    for(i = 0; i < codonsBefore; i++) {
        //Generate random codons until one that is not AUG has been generated
        while(1) {
            codon[0] = randomNucleotide();
            codon[1] = randomNucleotide();
            codon[2] = randomNucleotide();
            if(strcmp(codon, "AUG") != 0) {
                break;
            }
        }
        printf("%s",codon);
    }
    printf("AUG"); //Start
    //Do some initializations
    printGlutamicAcid(); //Set mem[0] to 1
    printAlanine(); //Set strg to 1
    printThreonine(); //Set ptr to strg == 1
    printGlutamicAcid(); //Set mem[1] to 1
    printTryptophan(); //Set strg to 0 (ptr is still 1)
    unsigned char curval = 1;
    while(1) {
        c = getchar();
        if(feof(stdin)) {break;}
        //Re-init *ptr to 1
        while(curval != c) {
            if(curval < c) {
                printArginine();
                curval++;
            } else if(curval > c) {
                printGlutamine();
                curval--;
            }
        }
        printLeucine();
    }
    printTerminator();
    //Print random codons after the terminator
    int codonsAfter = rand() % 1000;
        for(i = 0; i < codonsBefore; i++) {
                while(1) {
            codon[0] = randomNucleotide();
            codon[1] = randomNucleotide();
            codon[2] = randomNucleotide();
            //The RNA interpreter from
            if(strcmp(codon, "AUG") != 0) {
                break;
            }
        }
                printf("%s",codon);
        }

    //Free the memory occupied for generating a random codon
    free(codon);
}

How it works

In contrast to the text-to-Brainfuck-converter this converter doesn’t work deterministically but produces a different result every time it’s called.

Several factors contribute to this:

  • Between 0 and 1000 completely random (but not START) codons are prepended at the beginning
  • Between 0 and 1000 completely random (but not START) codons are appended at the end
  • Each The text to RNA converter usually yields pretty big files.

Have you considered hiding your valuable data in other ORFs ;-?