Lua进行二进制文件的位操作
1.纯lua的二进制位操作
lua的二进制文件主要利用string.byte()读取某个字节,string.char()写入,示例代码如下:
function v:xorFile(inputFile,outputFile)local fileIn,err = io.open(inputFile,"rb")local content = fileIn:read("*all")local length = fileIn:seek("end")fileIn:close()local fileOut,err = io.open(outputFile,"wb")fileOut:seek("set",0)local itemfor i=1,length doitem = tonumber(string.byte(content,i))item = bit:_xor(item,186)fileOut:write(string.char(item))endfileOut:close()
end
这是对整个二进制文件进行异或操作,那么对某个32位的uint如何操作?比如把第posSrc位的uint32异或posDst位的uint32
function v:XORuint32(inputFile,outputFile,posSrc,posDst)local fileIn,err = io.open(inputFile,"rb")local content = fileIn:read("*all")local length = fileIn:seek("end")fileIn:seek("set",0)local dataA = fileIn:read(posSrc-1)fileIn:seek("set",posSrc+4)local dataB = fileIn:read("*all")fileIn:close()local value1 = tonumber(string.byte(content,posSrc+1))local value2 = tonumber(string.byte(content,posSrc+2))local value3 = tonumber(string.byte(content,posSrc+3))local value4 = tonumber(string.byte(content,posSrc+4))local key1 = tonumber(string.byte(content,posDst+1))local key2 = tonumber(string.byte(content,posDst+2))local key3 = tonumber(string.byte(content,posDst+3))local key4 = tonumber(string.byte(content,posDst+4))value1 = bit:_xor(value1,key1)value2 = bit:_xor(value2,key2)value3 = bit:_xor(value3,key3)value1 = bit:_xor(value4,key4)local fileOut,err = io.open(outputFile,"wb")fileOut:seek("set",0)fileOut:write(dataA)fileOut:write(string.char(value1))fileOut:write(string.char(value2))fileOut:write(string.char(value3))fileOut:write(string.char(value4))fileOut:write(dataB)fileOut:close()
end
附上bit的代码
bit={data32={}}
for i=1,32 dobit.data32[i]=2^(32-i)
endfunction bit:d2b(arg)local tr={}for i=1,32 doif arg >= self.data32[i] thentr[i]=1arg=arg-self.data32[i]elsetr[i]=0endendreturn tr
end --bit:d2bfunction bit:b2d(arg)local nr=0for i=1,32 doif arg[i] ==1 thennr=nr+2^(32-i)endendreturn nr
end --bit:b2dfunction bit:_xor(a,b)local op1=self:d2b(a)local op2=self:d2b(b)local r={}for i=1,32 doif op1[i]==op2[i] thenr[i]=0elser[i]=1endendreturn self:b2d(r)
end --bit:xorfunction bit:_and(a,b)local op1=self:d2b(a)local op2=self:d2b(b)local r={}for i=1,32 doif op1[i]==1 and op2[i]==1 thenr[i]=1elser[i]=0endendreturn self:b2d(r)end --bit:_andfunction bit:_or(a,b)local op1=self:d2b(a)local op2=self:d2b(b)local r={}for i=1,32 doif op1[i]==1 or op2[i]==1 thenr[i]=1elser[i]=0endendreturn self:b2d(r)
end --bit:_orfunction bit:_not(a)local op1=self:d2b(a)local r={}for i=1,32 doif op1[i]==1 thenr[i]=0elser[i]=1endendreturn self:b2d(r)
end --bit:_notfunction bit:_rshift(a,n)local op1=self:d2b(a)local r=self:d2b(0)if n < 32 and n > 0 thenfor i=1,n dofor i=31,1,-1 doop1[i+1]=op1[i]endop1[1]=0endr=op1endreturn self:b2d(r)
end --bit:_rshiftfunction bit:_lshift(a,n)local op1=self:d2b(a)local r=self:d2b(0)if n < 32 and n > 0 thenfor i=1,n dofor i=1,31 doop1[i]=op1[i+1]endop1[32]=0endr=op1endreturn self:b2d(r)
end --bit:_lshiftfunction bit:print(ta)local sr=""for i=1,32 dosr=sr..ta[i]endprint(sr)
end
以上代码异或整个文件,1M的文件需要15秒左右,显然太慢,于是换个脚本,用python试试
2.python的二进制位操作
import binascii
import struct
import sysdef str2hex(str):hexs = []for s in str:tmp = (hex(ord(s)).replace('0x',''))if len(tmp) == 2:hexs.append(tmp)else:hexs.append('0'+tmp)return hexsarr= ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
arr2 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]def tran(r):for i in range(len(arr)):if r == arr[i]:return arr2[i]def packRes(input,output,key):f = open(input,'rb+')hexs = []while True:t = f.read(1)if len(t) == 0:breakhexs.extend(str2hex(t))f.close()ff = open(output,'wb')for i in range(len(hexs)):a = tran(hexs[i][0])*16+tran(hexs[i][1])B = struct.pack('B',a^key)ff.write(B)ff.close()def main(p1,p2,p3):print(p1)print(p2)print(p3)try:packRes(p1,p2,int(p3))sys.exit(0)except:sys.exit(1)finally:passif __name__ == "__main__":if len(sys.argv) >= 1:p1 = sys.argv[1]p2 = sys.argv[2]p3 = sys.argv[3]main(p1,p2,p3)
同样的文件要1秒左右,效率提升显著,然而还是不满足需求,还是试试C++吧
3.c++的二进制位操作
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib> int main(int argc, char* argv[])
{int i, count, len;int key;char buff[1024];static char tmpfile[] = "~u~0_sw~.f~l";FILE * in, *out;if (argc <3){printf("Less Parameter !\n");printf("Parameter number must at least 2 !!\n");return 1;}len = strlen(argv[2]);in = fopen(argv[1], "rb");out = fopen(tmpfile, "wb"); /* creat a temp file */key = std::atoi(argv[3]);if (in == NULL){printf("Input File \'%s\' not found !!\n", argv[1]);exit(1);}if (out == NULL){printf("Can not creat temp file \'%s\'\n", tmpfile);exit(2);}while (!feof(in)){count = fread(buff, 1, 1024, in);for (i = 0;i <count;i++)buff[i] ^= 119;//buff[i] ^= argv[2][i%len];fwrite(buff, 1, count, out);}fclose(in);fclose(out);//printf(argv[1]);//printf(argv[2]);if( strcmp(argv[1], argv[2]) == 0){remove(argv[1]);printf("the key is: %d", key);}rename(tmpfile, argv[2]);return 0;
}
注意再创建控制台应用程序的设置,不要预编译头,否则cpp在MAC下会不兼容。
1M左右,大概需要0.0006秒左右。因为我们最终是在lua脚本里用,所以接下来说下lua如何调用python
4.lua调用python和C
lua里面用os.excute来调用本地脚本。
首先看下调用python,由于python是跨平台的,MAC和WIN10下代码一致:
os.excute("python xxx.py inputFIle outputFile key")
在win10下调用控制台程序的话:VS新建控制台应用程序,调试成功后cd到exe 目录
os.excute("xxx.exe inputFIle outputFile key")
在mac下先cd到cpp目录用g++编译
g++ xxx.cpp
生成a.out
os.excute("./a.out inputFIle outputFile key")
5.小结
有人会喜欢那语言做比较,我认为语言是看场合的,就像你比较匕首和导弹,没有太大的意义。主要看武器在谁的手里,怎么去使用它。
上面对比来看,貌似python比lua效率高很多,然而,我们本不该在lua里面执行大体积二进制文件的位操作,Lua作为C的触手,应该在C里面绑定一个方法让lua调用,这样lua的效率就是C的效率(当然,要扣除一点调用C的成本)。
lua和python在不同场合有着各自的生命力。
Lua进行二进制文件的位操作相关推荐
- DTT的生活就是对吃的一种细细品味
最近买了DTT刚出的<愿所有的相遇,都恰逢其时>,看到这么一段话感觉很有味道."看一个家庭,可以看看他们的厨房.看一个人,可以看看他对吃的态度,爱吃的人大多会是有趣的,而有趣的人 ...
- windows mac 安装lua
mac从源码编译安装是最方便的,lua源码不足两万行,编译几秒钟的事. 打开terminal,依次输入以下命令: curl -R -O http://www.lua.org/ftp/lua-5.2.3 ...
- Java调用Lua(转)
Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些. 所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个 ...
- luajit开发文档中文版(二)LuaJIT扩展
2022年6月10日15:33:04 luajit开发文档中文版(一)下载和安装 luajit开发文档中文版(二)LuaJIT扩展 luajit开发文档中文版(三)FAQ 常见问题 luajit开发文 ...
- IoT入门概述与物联网安全基础
IoT入门概述与物联网安全基础 写在前面的话 IoT入门概述 IoT概述 物联网安全基础 物联网通信协议 物联网的基本架构 通信的上行和下行 物联网通信协议 传输协议与通信协议 IoT通信协议 物联网 ...
- Lua不同版本下的位操作
Lua不同版本下的位操作 Lua提供对变量的位操作,虽然可能不如直接用底层C实现起来效率高,但是聊胜于无吧.Lua历经几个大的版本变更,每个版本对应的位操作方式也是略有不同,本文主要记录lua 5.0 ...
- 【Lua】Lua知识点汇总
Lua知识点汇总 一.理解Lua的执行 二.Lua编译器 2.1 词法分析器 2.2 抽象语法树 2.3 语法分析 2.4 代码生成 三.Lua解析器 3.1 luac命令 3.2 二进制chunk格 ...
- 在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统
在<在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎>开始处,我提到某公司被指责使用"云命令"暗杀一些软件.本文将讲述如何去模拟一个 ...
- 在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎
前些天听到一个需求:某业务方需要我们帮忙清理用户电脑上的一些废弃文件.同事完成这个逻辑的方案便是在我们程序中加入了一个很"独立"的业务逻辑:检索和删除某个程序产生的废弃文件.试想, ...
最新文章
- 【Java工具类】使用Random类对象生成随机整数
- C库函数-perror()
- java exchange发邮件_java发送exchange邮件问题
- 微软分享史上最大基于Transformer架构的语言生成模型
- wcf 返回图片_WCF实现上传图片功能
- 梳理MVC 架构 MVVM架构
- Struts2的核心文件
- 12天学好C语言——记录我的C语言学习之路(Day 12)
- Scrapy爬虫基本使用
- java中重载 参数顺序_Java方法中的参数太多,第4部分:重载
- Android应用开发—FragmentManager如何管理fragments
- php nginx日志分析,如何通过NGINX的log日志来分析网站的访问情况,试试这些命令...
- 买二手房满二满五怎么理解?什么意思?
- 数字电路设计:竞争冒险以及消除方法
- 【12月英语博客】念念不忘,必有回响
- bios无cfg lock的情况如何disable cfg lock
- 我的PPT可以“吐泡泡”!你的可以吗?1分钟教会你怎么做
- 怎么运行python外星人入侵_Python入门项目:外星人入侵
- MySQL查询数据库里面所有的表名和表注释 - tables with comment
- ImageNet-trained CNNs are biased towards texture; increasing shape bias阅读笔记