Text-zu-Brainfuck/RNA-Konverter in ANSI C99
Brainfuck-Encoder
Das folgende kleine ANSI-C99-Programm liest einen String von stdin und gibt ein Brainfuck-Programm aus, das den gleichen String auf stdout ausgibt.
Kompilieren mit gcc -o bf bf.c
Verwendung:
cat my.txt | ./bf > my.bfQuellcode:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
unsigned char c;
unsigned char curval = 0;
//reg+1 mit 8 initialisieren
while(1) {
c = getchar();
if(feof(stdin)) {break;}
while(curval != c) {
if(curval < c) {
putchar('+');
curval++;
} else if(curval > c) {
putchar('-');
curval--;
}
}
putchar('.');
}
}Wie funktioniert es?
Im Wesentlichen verwendet es nur eines der Register der Brainfuck-Turing-Maschine und inkrementiert oder dekrementiert das Register, um das nächste Byte ausgeben zu können. Es verwendet keine der „fortgeschritteneren“ Funktionen in Brainfuck wie Schleifen.
Brainfuck-Decoder
unbf ist der entsprechende Decoder für bf – ein einfacher Brainfuck-Konverter, der nur die +, - und . Instruktionen interpretiert. Keine anderen Instruktionen werden interpretiert.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char c;
char curval = 0;
//reg+1 mit 8 initialisieren
while(1) {
c = getchar();
if(feof(stdin)) {break;}
if(c == '+') {
curval++;
} else if(c == '-') {
curval--;
} else if(c == '.') {
putchar(curval);
}
}
}Wenn man die Ausgabe von bf in unbf weiterleitet, ist die Ausgabe von unbf gleich der Eingabe von bf, mit anderen Worten:
cat my.txt | ./bf | ./unbfist äquivalent zu
cat my.txtRNA-Encoder
RNA ist eine wenig bekannte esoterische Sprache, die im esolangs.org-Wiki gelistet ist. Es gibt auch eine Referenzimplementierung für diese Sprache.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* Dies ist ein Text-zu-RNA [0]-Konverter
* Er liest einen Bytestream von stdin und erzeugt RNA-Code,
* der den von stdin gelesenen Bytestream ausgibt, wenn er
* in den Interpreter unter [1] eingegeben wird.
*
* Referenzen:
* [0]: http://esolangs.org/wiki/RNA
* [1]: http://esolangs.org/wiki/RNA/rna.c
*/
/**
* Gibt ein zufälliges von A,U,G und C zurück
*/
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)); //Um ein zufälliges Codon vor und nach dem "Gen" zu generieren
srand(time(0));
int codonsBefore = rand() % 1000;
int i;
for(i = 0; i < codonsBefore; i++) {
//Zufällige Codons generieren, bis eines gefunden wurde, das nicht AUG ist
while(1) {
codon[0] = randomNucleotide();
codon[1] = randomNucleotide();
codon[2] = randomNucleotide();
if(strcmp(codon, "AUG") != 0) {
break;
}
}
printf("%s",codon);
}
printf("AUG"); //Start
//Einige Initialisierungen durchführen
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;}
//*ptr neu auf 1 initialisieren
while(curval != c) {
if(curval < c) {
printArginine();
curval++;
} else if(curval > c) {
printGlutamine();
curval--;
}
}
printLeucine();
}
printTerminator();
//Zufällige Codons nach dem Terminator ausgeben
int codonsAfter = rand() % 1000;
for(i = 0; i < codonsBefore; i++) {
while(1) {
codon[0] = randomNucleotide();
codon[1] = randomNucleotide();
codon[2] = randomNucleotide();
//Der RNA-Interpreter von
if(strcmp(codon, "AUG") != 0) {
break;
}
}
printf("%s",codon);
}
//Speicher für das Generieren eines zufälligen Codons freigeben
free(codon);
}Wie es funktioniert
Im Gegensatz zum Text-zu-Brainfuck-Konverter arbeitet dieser Konverter nicht deterministisch, sondern erzeugt jedes Mal ein anderes Ergebnis, wenn er aufgerufen wird.
Mehrere Faktoren tragen dazu bei:
- Zwischen 0 und 1000 vollständig zufällige (aber nicht START) Codons werden am Anfang vorangestellt
- Zwischen 0 und 1000 vollständig zufällige (aber nicht START) Codons werden am Ende angehängt
- Der Text-zu-RNA-Konverter erzeugt normalerweise ziemlich große Dateien.
Hast du schon einmal darüber nachgedacht, deine wertvollen Daten in anderen ORFs zu verstecken ;-?