ANSI C99 中的文本转 Brainfuck/RNA 转换器
Brainfuck 编码器
以下小型 ANSI C99 程序从 stdin 读取字符串并打印出在 stdout 上打印相同字符串的 Brainfuck 程序。
使用 gcc -o bf bf.c 编译
像这样使用:
bf_usage.sh
cat my.txt | ./bf > my.bf源代码:
bf_encoder.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
unsigned char c;
unsigned char curval = 0;
//用 8 初始化 reg+1
while(1) {
c = getchar();
if(feof(stdin)) {break;}
while(curval != c) {
if(curval < c) {
putchar('+');
curval++;
} else if(curval > c) {
putchar('-');
curval--;
}
}
putchar('.');
}
}它如何工作?
基本上它只使用 Brainfuck 图灵机的一个寄存器,并递增或递减寄存器以便能够打印下一个字节。它不使用 Brainfuck 中任何更"高级"的功能如循环。
Brainfuck 解码器
unbf 是 bf 的对应解码器 - 一个简单的 brainfuck 转换器,只解释 +、- 和 . 指令。不解释其他指令。
unbf.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char c;
char curval = 0;
//用 8 初始化 reg+1
while(1) {
c = getchar();
if(feof(stdin)) {break;}
if(c == '+') {
curval++;
} else if(c == '-') {
curval--;
} else if(c == '.') {
putchar(curval);
}
}
}如果你将 bf 的输出管道到 unbf,unbf 的输出等于 bf 的输入,换句话说:
bf_pipe_example.sh
cat my.txt | ./bf | ./unbf等同于
cat_mytxt.sh
cat my.txtRNA 编码器
RNA 是一种不太知名的深奥语言,列在 esolangs.org wiki 上。也有此语言的参考实现。
rna_encoder.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* 这是一个文本转 RNA [0] 转换器
* 它从 stdin 读取字节流并生成 RNA 代码
* 当输入到 [1] 的解释器时打印从 stdin 读取的字节流。
*
* 参考:
* [0]: http://esolangs.org/wiki/RNA
* [1]: http://esolangs.org/wiki/RNA/rna.c
*/
/**
* 返回 A、U、G 和 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)); //为"基因"前后生成随机密码子
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"); //开始
//做一些初始化
printGlutamicAcid(); //将 mem[0] 设置为 1
printAlanine(); //将 strg 设置为 1
printThreonine(); //将 ptr 设置为 strg == 1
printGlutamicAcid(); //将 mem[1] 设置为 1
printTryptophan(); //将 strg 设置为 0(ptr 仍为 1)
unsigned char curval = 1;
while(1) {
c = getchar();
if(feof(stdin)) {break;}
//将 *ptr 重新初始化为 1
while(curval != c) {
if(curval < c) {
printArginine();
curval++;
} else if(curval > c) {
printGlutamine();
curval--;
}
}
printLeucine();
}
printTerminator();
//在终止子之后打印随机密码子
int codonsAfter = rand() % 1000;
for(i = 0; i < codonsBefore; i++) {
while(1) {
codon[0] = randomNucleotide();
codon[1] = randomNucleotide();
codon[2] = randomNucleotide();
//来自的 RNA 解释器
if(strcmp(codon, "AUG") != 0) {
break;
}
}
printf("%s",codon);
}
//释放为生成随机密码子占用的内存
free(codon);
}它如何工作
与文本转 Brainfuck 转换器不同,此转换器不是确定性工作,而是每次调用产生不同结果。
几个因素导致此情况:
- 在开头前置 0 到 1000 个完全随机(但不是 START)的密码子
- 在末尾追加 0 到 1000 个完全随机(但不是 START)的密码子
- 每个 文本转 RNA 转换器通常产生相当大的文件。
你有没有考虑过将你的宝贵数据隐藏在其他 ORF 中 ;-?
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow