BrainFuck——C实现BrainFuck解释器
首先介绍一下吊炸天的语言——BrainFuck
Brainfuck是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf**k,甚至被简称为BF
这种语言基于一个简单的机器模型,除了指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。
这种语言,是一种按照“Turing complete(完整图灵机)”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言,BrainF**k 语言只有八种符号,所有的操作都由这八种符号的组合来完成
(按照更节省时间的简单说法,"]"也可以说成“向后跳转到对应的"["状态”。这两解释是一样的。)
(第三种同价的说法,"["意思是"向前跳转到对应的"]"",]意思是"向后跳转到对应的[指令的次一指令处,如果指针指向的字节非零。")
Brainfuck程序可以用下面的替换方法翻译成C语言(假设ptr是char*类型):
当前位置清零
[-] 将当前指针的值归零
之前位置清零
[[-]<] 将当前指针以及之前的指针归零
字符I/O
,. 从键盘读取一个字符并输出到屏幕上。
简单的循环
,[.,] 这是一个连续从键盘读取字符并回显到屏幕上的循环。注意,这里假定0表示输入结束,事实上有些系统并非如此。以-1和"未改变"作为判断依据的程序代码分别是",+[-.,+]"和",[.[-],]"。
指针维护
>,[.>,] 通过移动指针保存所有的输入,供后面的程序使用。
加法
[->+<]
把当前位置的值加到后面的单元中(破坏性的加,它导致左边的单元被归零)。
为了方便我们理解BrainFuck语言,大家可以下载一个很好的编译器,里面还有很多demo
http://download.csdn.net/detail/sm9sun/9721483
下面给出两个示例:
一、程序输出hello word!
BF代码:++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.
程序输出小于输入数字的所有质数
BF代码:>++++++++[<++++++++>-]<++++++++++++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++++.[-]>++++++++++[<++++++++++>-]<+++++.[-]>++++++++++[<++++++++++>-]<+++++++++.[-]>++++++++++[<++++++++++>-]<+.[-]>++++++++++[<++++++++++>-]<+++++++++++++++.[-]>+++++[<+++++>-]<+++++++.[-]>++++++++++[<++++++++++>-]<+++++++++++++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++.[-]>+++++[<+++++>-]<+++++++.[-]>++++++++++[<++++++++++>-]<++++++++++++++++.[-]>++++++++++[<++++++++++>-]<+++++++++++.[-]>+++++++[<+++++++>-]<+++++++++.[-]>+++++[<+++++>-]<+++++++.[-]+[->,----------[<+>-------------------------------------->[>+>+<<-]>>[<<+>>-]<>>>+++++++++[<<<[>+>+<<-]>>[<<+>>-]<[<<+>>-]>>-]<<<[-]<<[>+<-]]<]>>[<<+>>-]<<>+<-[>+[>+>+<<-]>>[<<+>>-]<>+<-->>>>>>>>+<<<<<<<<[>+<-<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<<<>[>>+>+<<<-]>>>[<<<+>>>-]<<<<>>>[>+>+<<-]>>[<<+>>-]<<<[>>>>>+<<<[>+>+<<-]>>[<<+>>-]<[>>[-]<<-]>>[<<<<[>+>+<<-]>>[<<+>>-]<>>>-]<<<-<<-]+>>[<<[-]>>-]<<>[-]<[>>>>>>[-]<<<<<<-]<<>>[-]>[-]<<<]>>>>>>>>[-<<<<<<<[-]<<[>>+>+<<<-]>>>[<<<+>>>-]<<<>>[>+<-]>[[>+>+<<-]>>[<<+>>-]<>+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>-]<<-<-]+++++++++>[<->-]<[>+<-]<[>+<-]<[>+<-]>>>[<<<+>>>-]<>+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]>>>>[<<<<+>>>>-]<<<<>[-]<<+>]<[[>+<-]+++++++[<+++++++>-]<-><.[-]>>[<<+>>-]<<-]>++++[<++++++++>-]<.[-]>>>>>>>]<<<<<<<<>[-]<[-]<<-]++++++++++.[-]
是不是很神奇?
下面我们具体说一下思路:
假设我们要打印一个'A' A对应的ascii码为65,当然我们也可以用65个+,不过这样比较LOW
我们先用++++++表示把第一个空间增加到6,然后以此为循环进入第二个空间
每次循环让其加10,即++++++ [ > ++++++++++ < - ] >
此时我们在后面加一个. 运行一下++++++ [ > ++++++++++ < - ] > .输出的应该是一个<,即ascii为60
然后我们再在后面加5个+就能输出A了
好了下面我们输出一个I LOVE YOU试试
还是根据上面的原理,首先I(73),我们把他当作8*9+1来处理,即:++++++++ [ > +++++++++ < - ] > +.
之后我们可以将其变成空格(32),除了直接减去差值以外我们也可以将其归零然后重新赋值,用[-]归零,再加32
即:++++++++ [ > +++++++++ < - ] > +.[-]++++ [ > ++++++++ < - ] > .
然后写L(76),注意,当前值为32,我们可以使其加到38再*2,即:++++++++ [ > +++++++++ < - ] > +.[-]++++ [ > ++++++++ < - ] >.++++++[>++<-]>.
此时你应该输出的I L,看看是不是~~
所以~BrainFuck语言实现起来非常的自由,具体怎样写最简洁最大气就要看你的智商啦~~
接着我们再完成下面的字符输出
++++++++ [ > +++++++++ < - ] > +.[-]++++ [ > ++++++++ < - ] >.++++++[>++<-]>.+++.+++++++.-----------------.[-]++++ [ > ++++++++ < - ] >. -- [ >+++ < - ] >-.----------.++++++.
C语言实现解释器代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
char s[30000]={0};
char code[100000];
int len = 0;
int stack[100];
int stack_len=0;
int main(int argc,char**argv)
{char c;int i=0,j,k,x=0;FILE* f;char* p=s+10000;f=fopen(argv[1],"r");while(fread(&code[len],1,1,f)==1){len++;}setbuf(stdout,NULL);while(i<len) {switch(code[i]) {case '+':(*p)++;break;case '-':(*p)--;break;case '>':p++;break;case '<':p--;break;case '.':putchar((int)(*p));//printf("put:%hdn",*p);break;case ',':*p=getchar();break;case '[':if(*p) {stack[stack_len++]=i;} else {for(k=i,j=0;k<len;k++) {code[k]=='['&&j++;code[k]==']'&&j--;if(j==0)break;}if(j==0)i=k;else {fprintf(stderr,"%s:%dn",__FILE__,__LINE__);return 3;}}break;case ']':i=stack[stack_len-- - 1]-1;break;default:break;}i++;//x++;//printf("%d : i=%dn",x,i);}printf("\n");system("pause");return 0;
}
注:网上相关代码很多,但是大多数都有一个BUG,就是对于嵌套循环即[[]]这样的处理有误。
大家也可以测试输出质数的这个源码,其正好有一个嵌套循环。
然后我们也可以把BF代码保存为二进制文本,后缀名为bf(随便你啦)
再将我们的程序关联上
最后再让我们输出一下I LOVE YOU
好啦~大家现在又学会了一种语言说“我爱你”,还不赶紧去跟妹子表(zhuang)白(bi)~科科
BrainFuck——C实现BrainFuck解释器相关推荐
- HackTheBox - Brainfuck Write Up
OS:Linux DIFFICULTY:Insane 0x01 信息收集 端口扫描 + 指纹识别 naabu -host 10.10.10.17 -Pn -tp full -nmap-cli 'nma ...
- Brainfuck解释器(C#)
根据维基百科上的内容随手写的一个BF解释器,输入有两个参数--程序代码.输入流,返回内容为输出流.输入.输出均为字符串. 字符 含义 C语言替换 > 指针加一 ++ptr; < 指针减一 ...
- CTF writeup 0_IDF实验室
牛刀小试 1.被改错的密码 从前有一个熊孩子入侵了一个网站的数据库,找到了管理员密码,手一抖在数据库中修改了一下,现在的密码变成了 cca9cc444e64c8116a30la00559c042b4, ...
- aes离线解密工具_CTF常用工具、网站、练习平台
常用工具网站 CTFtools 比较全的工具下载网站,提供百度云链接 BUUCTF 比较全的工具下载网站,提供百度云链接 XSS 之旅 xss 攻击练习网站,闯关式设计,难度递增 too ...
- [Bugku][Crypto][CTF][2020]Crypto 1-20 write up
工具:CaptEncoder https://www.freebuf.com/sectool/188397.html Convert:https://pan.baidu.com/s/17YPXfvBH ...
- CTF爬虫:掌握这些特征,一秒识别密文加密方式
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 文章目录 前言 编码系列 Base 系列编码 Unicode 编码 Escape 编码 URL / Hex 编码 加密算法 MD ...
- 攻防世界MISC进阶区刷题记录
文章目录 攻防世界MISC进阶区刷题记录 Ditf 运用stegextract进行分离 glance-50 gif图片分离组合脚本 hit-the-core Test-flag-please-igno ...
- 刷题之旅第11站,ctfshow misc40
感谢@小白师傅提供的题目 感谢ctf show平台提供题目 下载题目文件后,打开压缩,一共四个文件 1.打开conversion.txt 按照下面提示,依次进行进制转换得到 202013 这串数字后面 ...
- 【日常记录】CTF审查清单(linux)
白刀破金甲 欢迎大佬补充 恳求大佬补充 感谢大佬补充 检查清单 白刀破金甲 一.常用工具 常用代理设置 nmap curl dirb dirsearch gobuster nikto wpscan w ...
最新文章
- UpSetR:多数据集绘图可视化处理利器
- TCP数据流稳定性--TCP分片,重组及乱序
- 防止重复提交保证幂等的几种解决方案
- who are you really?
- python四种可变类型_SICP Python 描述 2.4 可变数据
- solaris11 format zpool
- MVC利用URLRoute实现伪静态后正真的静态html无法访问
- extern 关键字的作用
- mybatis入门截图四(订单商品数据模型-懒加载-缓存)
- 【完美解决】arcgis engine 10.0 for cross platform C++ 在visual studio2010上编译的AE程序 的License无法初始化错误。...
- 免费的机器人聊天接口
- 如何关闭伽卡他卡的开机自启
- Fine BI、Smart BI、永洪BI、瓴羊Quick BI这些国产BI工具,都擅长哪些功能?
- 最强 Python 数据可视化库,没有之一!
- 演出遭遇枪击 前Pantera吉他手不幸身亡
- expect hope wish区别
- etcdctl-管理操作etcd集群
- 国际快递 什么是国际快递物流
- CAN光端机在西门子FC18/720消防主机海上风电厂之星型联网方式
- 一位中科院自动化研究所博士的论文致谢:求学22载,计算机终成一生的事业与希望...
热门文章
- python惰性求值效果_让Python中类的属性具有惰性求值的能力
- 编译C/C++为dll供Python调用
- NumPy Matplotlib PIP安装
- STM32那点事(3)_中断(上)
- 2 RepMLP:卷积重参数化为全连接层进行图像识别 (Arxiv)
- Linux下监视NVIDIA的GPU使用情况
- 录音喊话器的故障修理_我司quot;XAHHQ1型quot;喊话器 通过公安部检测
- python3 正则 去除 html标签、提取正文内容_Python通过正则表达式去除(过滤)HTML标签,提取文字...
- wampserver启动报错:1 of 2 services running - 解决篇
- 带音乐动态手机壁纸小程序源码-带自动采集-更新功能