跳至主要内容

博文

用C语言写解释器(三)

用C语言写解释器(三)——中缀转后缀 redraiment, 2009-11-01 操作符排序   如果你忘记了后缀表达式的概念,赶紧翻回上一篇《 用C语言写解释器(二) 》回顾一下。简单地说,将中缀表达式转换成后缀表达式,就是将操作符的执行顺序由“优先级顺序”转换成“在表达式中的先后顺序”。因此,所谓的中缀转后缀,其实就是给原表达式中的操作符排序。   比如将中缀表达式 5 * ((10 - 1) / 3) 转换成后缀表达式为 5 10 1 - 3 / *。其中数字 5 10 1 3 仍然按照原先的顺序排列,而操作符的顺序变为 - / ×,这意味着减号最先计算、其次是除号、最后才是乘号。也许你还在担心如何将操作符从两个操作数的中间移到它们的后边。其实不用担心,在完成了排序工作后你就发现它已经跑到操作数的后面了 ^_^。   从中缀表达式 1+2×3+4 中逐个获取操作符,依次是 + × +。如果当前操作符的优先级 不大于 前面的操作符时,前面操作符就要先输出。比如例子中的第二个加号,它前面是乘号,因此乘号从这个队伍中跑到输出的队伍中当了“老大”;此时第二个加号再前面的加号比较,仍然没有比它大,因此第一个加号也排到新队伍中去了;最后队伍中只剩下加号自己了,所以它也走了。得到新队伍里的顺序 × + + 就是所求解。下面的表格中详细展示每一个步骤。 序号 输入 临时空间 输出 1 + 2 × + 3 + + × 4 + × + 5 + + × 6 + × + 7 * + +   相信你心里还是牵挂着那些操作数。很简单,如果碰到的是操作符就按上面的规则处理,如果是操作数就直接输出!下面的表格加上了操作数,将输出完整的后缀表达式。 序号 输入 临时空间 输出 1 1 2 + 1 3 2 + 1 4 × + 1 2 5 3 + × 1 2 6 + + × 1 2 3 7 + × + 1 2 3 8 + + 1 2 3 × 9 4 + 1 2 3 × + 10 + 1 2 3 × + 4 11 1 2 3 × + 4 +   得到最终结果 1 2 3 × + 4 + 就是所求的后缀表达式。下面是程序中的参考代码(有删减)。 操作符优先级   上一节介绍了中缀转后缀的方法。其中关键...

用C语言写解释器(二)

用C语言写解释器(二)——表达式求值 redraiment, 2009-10-31 内存管理   既然是表达式求值,自然需要在内存中保存计算结果以及中间值。在《 用C语言写解释器(一) 》中提过:变量要求是若类型,而 C 语言中的变量是强类型,为实现这个目标就需要定义自己的变量类型,参考代码如下(注释部分指出代码所在的文件名,下同): // in basic_io.h #define MEMERY_SIZE (26) typedef enum {     var_null = 0,     var_double,     var_string } variant_type; typedef char STRING[128]; typedef struct {     variant_type type;     union {         double i;         STRING s;     }; } VARIANT; extern VARIANT memery[MEMERY_SIZE]; // in expression.h typedef VARIANT OPERAND;   程序自带 A-Z 26个可用变量,初始时都处于未赋值(ver_null)状态。所有变量必须先赋值再使用,否则就会报错!至于赋值语句的实现请参见后面语法分析的章节。 操作符   表达式中光有数值不行,还需要有操作符。在《 一 》中“表达式运算”一节已经给出了解释器需要实现的所有操作符,包括“算术运算”、“关系运算”和“逻辑运算”。下面给出程序中操作符的定义和声明: // in expression.h typedef enum {     /* 算数运算 */     oper_lparen = 0,    // 左括号     oper_rparen,   ...

用C语言写解释器(一)

用C语言写解释器(一)——我们的目标 redraiment, 2009-10-18 起因   最近,我们学院老师联系我,希望我能提供一段用 C 语言编写的 BASIC 解释器,用于 C 语言课程设计教学。我前段时间也正好着迷于“语言”本身,本就有打算写一个解释器,这下正中我下怀,于是欣然接受。   以前在图书馆看过梁肇新的《编程高手箴言》,第四章“编程语言的运行机理”中就包含了一段 C 语言编写的 BASIC 解释器代码,但代码好像并不完整(我翻了好几遍,都没发现函数 get_token 的实现代码);再者,这次的代码还有其他用处,不宜牵涉版权问题;最后的原因是我有“想自己编码”的冲动 ^_^。综上所述,我要从零开始用 C 语言来编写一个 BASIC 解释器。 前置知识   1. 要编写解释器,首先就要明白什么是解释器(详细的解释请参看维基百科: http://zh.wikipedia.org/zh-cn/解释器 )。盗用《编程高手箴言》里的话: 解释程序就是一个字符串的解释器 (P165 解释语言的原理)。所以,如果仅仅是为我个人编写的话,我宁可会借助 lex & yacc 甚至 perl,而不会纯粹用 C 语言来写。   2. 在起因中已经提过,这个程序会在学弟学妹们学完 C 语言后作为综合实验。因此需要你熟悉 C 语言的语法、单链表添加/删除节点等操作以及栈的概念(这些内容大部分都能在 C 语言的教材中找到),一些相对冷僻的技术(例如 setjmp/longjmp)则不会出现在程序中。 关于语言   我在《 编程和语言之我见 》一文中提过,编程是一个很宽泛的概念。从某种意义上来说所有的软件都是一种特定的语言,但根据程序本身的灵活性可以分为“硬编码”、“可配置”、“可控制”和“可编程”四类(详见《 四类程序 》)。如果一个程序的灵活性达到了“可编程”,它的配置文件就可以被看作一种“编程语言”,而该程序本身也就是一个“解释器”。   要做到“可编程”,程序至少应该具备“输入/输出”、“表达式运算”、“内存管理”和“按条件跳转”四个功能(详见《 用DOS批处理来做数字图像处理 》)。这正好对应了冯·诺依曼计算机的结构:以运算器和控制器为中心,输入/输出设备与存储器之间的数据传输都要经过运算器。下面...

庆中秋:用Windows XP桌面图标玩贪吃蛇(原理)

庆中秋:用Windows XP桌面图标玩贪吃蛇(原理) redraiment, 2009-10-04 到处都有好玩的玩意儿   计算机的世界里离散的:内存从 0 -> 2n 编号;整个屏幕的画面也是由许多颗像素点组成……如果你不介意的话,把脸尽量地贴近显示器(或者电视屏幕),你会看到整个屏幕是由一颗颗显示不同颜色的小颗粒拼成的。如果这样感受还不深,那你还记得小时候玩过的最初型掌上游戏机吗?如下图:   其中经典的飞机、坦克、俄罗斯方块等都是由一个个正方形的黑色方块拼成的。   放眼周边的世界,到处都有这样规则排列的、方方正正的“游戏元素”:摩天大楼的窗户、大教堂的座位、从楼上往下看的人群……当然还有今天要介绍的桌面图标!在优库上一搜索就会出现很多结果,有用寝室楼电灯玩贪吃蛇的、也有军训时集体玩 AK47 阵列的等等,原理都是这样~   在看完这篇文章后,你也可以尝试照样画葫芦,比如开启很多个“记事本”,将他们的窗口调整成四四方方的,然后用它们玩俄罗斯方块。 ^_^ 程序原理   我在优库上发布了视频——用 Windows XP 桌面图标玩贪吃蛇(视频地址为  http://v.youku.com/v_show/id_XMTIyODk2Njky.html ),一些朋友在评论中猜测程序原理:有人说是用批处理,还有人说是用汇编,甚至有人直接否定说是我用静态帧拼接起来的,呵呵。其实没大家想的这么复杂,我的程序主要是用 VB 开发的(为方便以后使用,移动桌面图标的代码用 C 语言写,并打包成 DLL 文件。程序的核心语句就是下面这句话: SendMessage ( hwnd, LVM_SETITEMPOSITION, i , MAKELPARAM( x , y ) );    SendMessage 是系统调用,可以向指定的窗口发送消息。整条语句的作用是向桌面发送消息,请求将第“ i ”个图标移动到坐标“ x,y ”位置。下面按照视频里播放的顺序依次介绍原理: 一、创建文件   在视频的最开始,我开启了一个命令提示符执行一条命令。可能正是因为这个原因让大家误以为这个程序是用批处理写的。如果你看了我上次的高清AVI版视频,就知道我命令是:“ for /l %d in (1,1,16) do echo. >%d.txt ”。正如网友“ Syp...

迎国庆,DuplexPipe 发布 0.3.0 版

迎国庆,DuplexPipe 发布 0.3.0 版 redraiment, 2009-10-01   今天是中华人民共和国建国六十周年,普天同庆!作为一个程序员,当然是努力工作报效祖国啦~特地抽空完善 DuplexPipe ,主要更新如下: 实现了 UDP 通信模式; 增加了对多语言的支持,Download 中提供中文版,你还可以通过源码自行编译英文版; 修正了一些 v0.1.0 中的小错误。   最新版的源码以及 JAR 包请到项目主页( http://code.google.com/p/duplexpipe/ )下载。有了 UDP 模式,现在连接模式一共有以下四种: TCP 监听模式 TCP 连接模式 UDP 监听模式 UDP 连接模式   根据两个连接模式排列,可以得到 4×4=16 种模式。由于类似“ TCP 监听模式 -  TCP 连接模式”和“ TCP 连接模式 - TCP 监听模式”等模式属于同一种,排除重复项后总共剩下以下十种模式: TCP  监听模式 -  TCP  监听模式 TCP  监听模式 -  TCP  连接模式 TCP  监听模式 -  UDP  监听模式 TCP  监听模式 -  UDP  连接模式 TCP  连接模式 -  TCP  连接模式 TCP  连接模式 -  UDP  监听模式 TCP  连接模式 -  UDP  连接模式 UDP  监听模式 -  UDP  监听模式 UDP  监听模式 -  UDP  连接模式 UDP  连接模式 -  UDP  连接模式   到这里还没有结束。我们知道 UDP 属于非安全连接,通讯之前没有经过三次握手确认。因此在“ UDP 连接模式端”发送数据包到“ UDP 监听模式端”之前,“监听端”并不知道“连接端”的位置,所以也就无法主动给“连接端”发送数据。而我们的 DuplexPipe 只是一个数据转发工具,本身并不向两端程序发送任何...

批量检测可用域名

批量检测可用域名 redraiment, 2009-09-25   在《 内网 IP 自动获取 》的评论中,有个网友希望能帮忙写一个批处理来批量检测域名的可用性。但前两天都在赶文档,刚刚接到老师电话说推迟到 10 月 08 日交,心头大石终于落地 ^_^ 。所以就马上开工帮那位朋友实现这个批处理!   原理很简单,就是找一个域名注册网站(比如我这里找的中国域名为 http://www.chinadomain.com.cn/ ),这类网站一般都提供了域名查询功能,我们只要用 curl 等命令行 Web 客户端来提交表单就能获得域名的信息,然后通过 grep 来提取可用域名。    注 :这两个工具在 Linux 系统中是自带的,但 Windows 中没有。我已经将它们和批处理文件一起上传到我的 Google Sites ( https://sites.google.com/site/redraiment/sunshine/domain )里,方便大家下载。下面是批处理的代码: :: 查询可用域名 :: 使用方法:domain.bat hostname ... :: By redraiment @echo off :loop if "%1"=="" goto end curl "http://www.chinadomain.com.cn/whoischeck.asp?domain_type=en_domain&ifcn=en&name=%1&imageField44.x=0&imageField44.y=0&suffix=.com&suffix=.com.cn&suffix=.cn&suffix=.net&suffix=.net.cn&suffix=.org&suffix=.org.cn&suffix=.biz&suffix=.info&suffix=.mobi&suffix=.tel&suffix=.me&suffix=.cc&suffix=.hk&suffix=.tv&suffix=.asia&suffix=.name&s...

内网IP自动获取V2

内网IP自动获取V2 redraiment, 2009-09-24   为解决上内网问题,我需要找一个 DHCP 未分配的 IP 地址来使用,在《 内网 IP 自动获取 》一文中的批处理能成功实现自动搜索。原理是逐个尝试地址是否可用,测试方法就是将本地地址设置成指定的静态 IP ,然后去 ping 网关,直到找到一个成功的地址。但这种方法有些美中不足: 通过 netsh 设置本地静态 IP 比较耗时间; 如果 IP 已经被分配就会弹出一个消息框需要手工确认,因此并不算真正的自动化。   在前一篇评论里也有朋友在问,能 ping 通的主机就是在线主机,这样只要搜索不能 ping 通的 IP 地址即可。其实不然,大部分防火墙默认都开启了防 ping 规则, ping 都会被拦截,因此即使在线也 ping 不通。但转念一想:如果主机在线,它的物理地址机会记录在 ARP 列表里,在 ping 完一个地址后到 ARP 列表中检查是否存在该地址的记录,就可以确定这个地址是否已经被 DHCP 分配出去!用下面的代码去替换《 内网 IP 自动获取 》中的 scan 模块: :scan arp -d for /l %%d in (2,1,253) do (   ping -n 1 %~n1.%%d & arp -a | find " %~n1.%%d "   if ERRORLEVEL 1 (     netsh int ip set address "本地连接" static %~n1.%%d 255.255.255.0 %1 1     ping -w 10 -n 1 %1 | find /I "TTL"     if NOT ERRORLEVEL 1 (       netsh int ip set dns "本地连接" static 210.33.88.1 primary       exit     )   ) )   这段代码只在最终找到可用地址后才设置本地地址,执...

内网IP自动获取

内网IP自动获取 redraiment, 2009-09-23   在寝室上内网真的是很闹心呀~稍微迟点开机, IP 地址就被别人抢去了。昨晚九点放学后,一直等到十点半才连上,实在忍无可忍了!    IP 被抢后解决方法无非就是找一个没被占用的地址,但手工去测试 256 个地址太折磨人了,早些时候我们班的两个同学就分别用 Java 和 C# 来实现过类似的小工具。但解决这样的小问题有点杀鸡用牛刀的感觉,不符合我的性格 ^_^ ,我当然还是用批处理来解决。   批处理中核心的两条语句就是: 设置静态IP地址 netsh int ip set address "本地连接" static IP地址 子网掩码 网关 1 设置域名解析器 netsh int ip set dns "本地连接" static 域名解析器地址 primary   程序使用时需要提供一个网关地址,为了方便大家使用,在 XP 和 Vista 系统能自动检测网关地址,如果正确的话直接敲一个回车就可以了。下面是批处理的代码,大家只要将下面的代码复制到记事本里,另存为 sip.bat ,双击即可运行。 :: 自动查找可用 IP :: 适用于浙江工商大学 :: by redraiment @echo off setlocal enabledelayedexpansion if NOT "%1"=="" goto scan :: 检测可识别的系统版本 :: XP ver | find "[版本 5" if NOT ERRORLEVEL 1 (   set SV=XP   set CG='"ipconfig|find /I "gate""'   set TS=13 ) :: VISTA ver | find "[版本 6" if NOT ERRORLEVEL 1 (   set SV=VISTA   set CG='"ipconfig|find /V "::"|find "网关""'   set TS=15 ) if NOT ...

解决 Debian 升级后小键盘失效

解决 Debian 升级后小键盘失效 redraiment, 2009-09-11   经过两个月的假期,寝室里蒙上了厚厚的一层灰。擦桌子、拖地、刷马桶……忙得不亦乐乎!回到实验室,第一件事就是“ aptitude update && aptitude upgrade ”。   经过一段不算漫长的等待, Debian 以崭新的面貌展现在我面前。但想输入密码的时候发现小键盘没反应了:按“ Num Lock ”指示灯还会改变,回车也依然有效,按数字却就“没反应”。再仔细观察一下,发现按“8、2、4、6”时,鼠标指针分别按“上、下、左、右”移动。莫非这就是传说中的“鼠标键”?   打开“键盘手选项”,切换到“鼠标键”,“允许键盘控制鼠标指针”这个选项果然是选中了,去掉后就恢复正常了。难道升级后覆盖了原来的配置文件,大家有没有遇到过这个问题?

DuplexPipe二三事(六)——没有第七

DuplexPipe二三事(六)——没有第七 redraiment, 2009-09-04 我的设想   在着手编写 DuplexPipe 之前,我规划过我的需求:我想要一个最通用的通信工具,换言之就是能让所有具有输入/输出的程序都可以相互通信。 DuplexPipe 本身远没达到这个设想,至少还得具备以下几中模式: -f file       # 通过读写文件获得数据 -s            # 从 stdio 中获得数据 -e exefile    # 从本地程序的输入输出中获得数据 -r url        # 这是一个附加功能。如果你玩过几天木马,你可能也渴望将它变成一个强大的后门!通过这个选项可以从URL中获得IP地址和端口,主动进行连接。 没有第七   但我会很遗憾的宣布,上述功能不会被加入 DuplexPipe 中。这也意味着介绍 DuplexPipe 到此为止,不会再有《 DuplexPipe 二三事(七)》,关于 DuplexPipe 维护的动态则会更新在项目主页 http://code.google.com/p/duplexpipe/ 中。   你可能听说过:“一篇文章的完成不是再也不能往里面加内容,而是再也没法删内容时。”写程序也是如此。我们来看上面提到的四个功能: -f file       # 这条可以最先被排除,因为主流的系统都支持输入输出重定向('<'、'>'和'>>')。 -s            # -s 和 -e 两种模式 nc 都支持!写程序也很机会重复制造车轮。 -e exefile    # 理由同上 -r url        # 这个功能虽然诱人,但很明显和主要功能无关,没必要保留。   因此,前三个功能都可以通过和 nc 配合来完成(瑞士军刀 nc 的使用方法请参看《 DuplexPipe 二三事(二) 》)!而且现在 Http Client 遍地开花(例如 ...

DuplexPipe二三事(五)——来自内网的呼唤

DuplexPipe二三事(五)——来自内网的呼唤 redraiment, 2009-09-04 穿越防火墙   你是否曾经尝试过去连接一台远程计算机,却因为被防火墙拦截或路由器没有转发而造成无法通信?这是主动式连接的一个弊端:它依赖服务器的状态,而对服务器有生杀大权的只有管理员。如果能让服务器主动尝试连接我们的计算机,那就没问题了!因为防火墙、路由等一般不会过滤向外的连接(反弹式木马就是利用这一原理)。   但以往的服务端程序都是采用监听本地端口的方式(比如 Windows 远程桌面程序监听本地 3389 端口),我们需要将它的连接方式改成主动连接外部网络的方式。我想你也一定要将想到(如果你看过《 DuplexPipe 二三事(四) 》),用 DuplexPipe 来转换它的连接方式! 反弹式远程桌面   在此以 Windows 远程桌面为例,演示如何用一个正向连接的程序实现反向连接。本次演示的环境: 主机 A(客户端) :处于外网, IP 地址为  60.180.*.* 。系统环境为 Vista 家庭版,自带远程桌面连接客户端; 主机 B(服务端) :处于内网。系统环境为 Win XP SP2 ,并开启了远程桌面服务 。   具体操作步骤如下:   一、将客户端的“连接式”转换为“监听式”。 打开命令提示符,执行: java -jar DuplexPipe.jar -l 1234 -l 3389      二、将服务器端“监听式”转换为“连接式”,并连接客户端监听的 1234 端口。 打开命令提示符,执行: java -jar DuplexPipe.jar -c 60.180.*.* 1234 -c localhost 3389      三、启动客户端上的远程桌面连接程序,连接本地的 3389 (默认)端口,即可连接成功!      连接成功后:    总结   如果你能理解上面的操作,就可以照样画葫芦去连接任何其他程序!我在前面提到过, DuplexPipe 目前还有待完善,那它以后还会添加些什么功能?会不会发展成为一个反弹式木马?请看《 DuplexPipe 二三事(六)》。

DuplexPipe二三事(三)——网络中转站:端口映射

DuplexPipe二三事(三)——网络中转站:端口映射 redraiment, 2009-09-03 端口映射   在《 DuplexPipe 二三事(二) 》中介绍了瑞士军刀 nc 的用法: nc 就像给程序一张飞机票,让原本只能在本地执行的程序也能运行在网络上!但网络和现实交通一样,很多地方需要中转才能到达(比如外网计算机无法直接访问公司内部 Web 服务器)。   为实现公网对内部网络的访问,需要对数据进行转发(即端口映射)。比如内网“主机 A ”开启了 Web(port 80) 服务,需要在“服务器的网关”上设置:凡来自 Internet 上对 80 端口的请求,全部转发给内部网络中的“主机 A ”。这里的“服务器网关”可以是路由器、交换机或者一台 PC 。 工具简介    FPipe 是一款命令行下的端口映射工具,可以映射 TCP/UDP 协议,支持连接数的最大上限。你可以从它的官网( http://www.foundstone.com )下载到最新版本。下面是它的用法和几个常用的选项: FPipe [-hvu?] [-lrs <port>] [-i IP] IP   -l 在本地监听的端口   -s 从哪个端口发送出重定向的信息   -r 要定向到IP主机的端口号   -u UDP 模式   -v 详细地显示过程 示例:   FPipe -v -l 80 -s 90 -r 80 192.168.1.100   作用就是将来自本机80端口的信息,通过90端口,转发到主机192.168.1.100的80端口上去。   你可以尝试执行:“ FPipe -l 80 -s 80 -r 80 203.208.39.160 ”,然后访问“ http://localhost/ ”就会打开 Google 首页,因为 203.208.39.160 就是  Google  主机的  IP  地址,^_^。更多的内容请参见程序附带的帮助文档。 总结   对于在《 DuplexPipe二三事(一) 》中提出的“进程通信”问题, nc 可以让本地程序通过网...

DuplexPipe二三事(四)——网络连接方式随心换

DuplexPipe二三事(四)——网络连接方式随心换 redraiment, 2009-09-04 连接方式   在《 DuplexPipe二三事(一) 》中提到建立连接有两种方式:监听本地端口,等待其他程序来连接(以下简称“监听方式”);或者主动连接其他程序(以下简称“连接方式”)。排列组合一下,会得到三种结果:监听-连接、监听-监听、连接-连接。其中只有“监听-连接”方式能正确地建立连接,《 DuplexPipe 二三事(三)》中介绍的 FPipe 只是在其中添加了一节“监听- 连接-监听 -连接”,其中粗体部分就是 FPipe 的工作。   那有没有办法让“监听-监听”、“连接-连接”这两种方式也能通信呢?或者说,有没有办法在不修改程序的前提下转换它的连接方式?这就是 DuplexPipe 提供的功能! DuplexPipe简介    DuplexPipe 和 FPipe 类似,也是命令行下的转发工具,但它允许你自己选择连接方式,因此比 FPipe 更加灵活!DuplexPipe 目前还只有 Java 实现方式,开放源代码,目前还不支持 UDP 模式。欢迎有兴趣的同学一起参与开发和维护!项目主页: http://code.google.com/p/duplexpipe 。下面来介绍一下它的选项和用法: 用法: java -jar DuplexPipe [-vh] model model 选项:         -v              输出一些提示信息         -h              显示本帮助文档 模式:         -l port         监听本地端口         -c host port    连接远程端口 示例:         java pipe.Dup...

DuplexPipe二三事(二)——瑞士军刀再显锋芒:让程序相互聊天

DuplexPipe二三事(二)——瑞士军刀再显锋芒:让程序相互聊天 redraiment, 2009-09-02 瑞士军刀NC    nc(NetCat) 是我很喜欢的一个小工具。在我常用的网络小工具中使用频率仅次于 cURL 。 nc 属于传输层的工具( TCP/IP  四层模型请看 这里 ),它能保证准确无误地发送和接收数据,但并不关心数据的具体含义(这些工作交给应用层的软件)。难怪说 nc 是网络的瑞士军刀,因为所有应用层的软件都是通过各自的网络协议来解析来自传输层的数据。所以,只要你了解应用层协议(比如HTTP、POP3等),就可以手工模拟出任何服务端或客户端程序。而且,只要你愿意,以后设计网络程序完全可以只实现一个“解析器”,数据传输的工作则全权交给 nc 了。 常用功能   网络程序要建立连接有两种方式:主动去连接、监听本地端口等待连接。nc 也提供了这两种方式: 1) nc host port     主动连接 host 的 port 端口。 2) nc -l -p port     监听本地 port 端口,等待其他程序来连接。 示例:     运行 nc g.cn 80     这样就连接上“谷歌中国”的服务器,输入“ GET / HTTP/1.1<CR><CR> ”(不包括引号,其中<CR>是回车,这里需要敲两次回车),服务器就会返回“谷歌”首页的 HTML 源代码。   上面是一个网络程序最基本的功能,默认下输入输出为 stdin 和 stdout (也就是“键盘”和“屏幕”)。nc 让我最欣赏的就是“ -e ”选项,通过它能将输入输出重定向到本地可执行程序。例如在 windows 环境下执行: nc -l -p 1234 -e cmd.exe   这样,从端口 1234 获得的数据都会转发给 cmd.exe ,而 cmd.exe 的输出也会返回给网络。此时的 nc 就像一件外衣罩在 cmd.exe 上,让原本不具备网络通信功能的 cmd.exe 也成为网络程序。 更多关于 nc 的用法可以参见 这里 。 程序自动“聊天” ...

DuplexPipe二三事(一)——有趣的起因:算24

DuplexPipe二三事(一)——有趣的起因:算24 redraiment, 2009-09-02   写 DuplexPipe 是因为“无聊”!真的,那天很无聊,想起小时候用扑克牌和姐姐比赛算24,就随手写了一个 Shell 脚本重温一下: #!/bin/sh for (( i = 0;i<4;i++ )) do     (( n = $RANDOM % 10 + 1 ))     echo -n " $n " done echo i = 0 while read exp do     (( i++ ))     (( value = $exp ))     if [[ $value -ne 24 ]]     then         echo -n " Wrong! "         echo " $exp = $value "         echo " try again! "     else         echo " OK! "         echo " Total use ${i} s "         break     fi done   最近好像养成一个习惯:能让计算机自动处理的尽量不制作。才玩了几盘,就开始动歪脑筋要写一个求24的程序来自动计算。方法就是最简单的穷举,下面是一个最初的简陋版本(有兴趣的朋友可以在此再添加五种括号): #!/bin/sh s[ 0 ]=' + ' s[ 1 ]=' - ' s[ 2 ]=' * ' s[ 3 ]=' / ' read a b c d for (( i =0;i<64;i++)) do    ...