update test/md5.nas(still has bug) & add libmd5 in module(written in C++)

This commit is contained in:
ValKmjolnir 2022-03-28 17:14:11 +08:00
parent 617ad03d33
commit dd7740f1fd
5 changed files with 344 additions and 69 deletions

8
module/libmd5.nas Normal file
View File

@ -0,0 +1,8 @@
import("lib.nas");
var md5=func(str){
var lib=dylib.dlopen("./module/libmd5"~(os.platform()=="windows"?".dll":".so"));
var res=dylib.dlcall(dylib.dlsym(lib,"nas_md5"),str);
dylib.dlclose(lib);
return res;
}

View File

@ -11,5 +11,12 @@ libkey.so: keyboard.cpp
libkey.dll: keyboard.cpp
g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
g++ -shared -o libkey.dll keyboard.o -static
libmd5.so: md5.cpp
clang++ -c -O3 md5.cpp -fPIC -o md5.o
clang++ -shared -o libmd5.so md5.o
rm md5.o
libmd5.dll: md5.cpp
g++ -c -O3 md5.cpp -fPIC -o md5.o -static
g++ -shared -o libmd5.dll md5.o -static
clean:
rm *.o *.so *.dll *.dylib

105
module/md5.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "../nasal.h"
uint32_t strlength;
uint32_t* add(std::string str)
{
uint32_t num=((str.length()+8)/64)+1;
uint32_t *strByte=new uint32_t[num*16];
strlength=num*16;
for (uint32_t i=0;i<num*16;i++)
strByte[i]=0;
for (uint32_t i=0;i<str.length();i++)
strByte[i>>2]|=(str[i])<<((i%4)*8);
strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);
strByte[num*16-2]=str.length()*8;
return strByte;
}
std::string changeHex(int a)
{
const char str16[]="0123456789abcdef";
std::string str="";
for(int i=0;i<4;i++)
{
std::string str1="";
int b=((a>>i*8)%(1<<8))&0xff;
for (int j = 0; j < 2; j++)
{
str1.insert(0,1,str16[b%16]);
b=b/16;
}
str+=str1;
}
return str;
}
std::string md5(std::string source)
{
// uint32_t(abs(sin(i+1))*(2pow32))
const uint32_t k[]={
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
};
// left shift
const uint32_t s[]={
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
// index
const uint32_t idx[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // g=i
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, // g=(5*i+1)%16;
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, // g=(3*i+5)%16;
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 // g=(7*i)%16;
};
uint32_t atmp=0x67452301,btmp=0xefcdab89;
uint32_t ctmp=0x98badcfe,dtmp=0x10325476;
uint32_t *strByte=add(source);
#define shift(x,n) (((x)<<(n))|((x)>>(32-(n)))) // cycle left shift
#define F(x,y,z) (((x)&(y))|((~x)&(z)))
#define G(x,y,z) (((x)&(z))|((y)&(~z)))
#define H(x,y,z) ((x)^(y)^(z))
#define I(x,y,z) ((y)^((x)|(~z)))
for(uint32_t i=0;i<strlength/16;i++)
{
uint32_t num[16];
for(uint32_t j=0;j<16;j++)
num[j]=strByte[i*16+j];
uint32_t f,g,a=atmp,b=btmp,c=ctmp,d=dtmp;
for(uint32_t i=0;i<64;i++)
{
if(i<16) f=F(b,c,d);
else if(i<32) f=G(b,c,d);
else if(i<48) f=H(b,c,d);
else f=I(b,c,d);
uint32_t tmp=d;
d=c;
c=b;
b=b+shift((a+f+k[i]+num[idx[i]]),s[i]);
a=tmp;
}
atmp+=a;
btmp+=b;
ctmp+=c;
dtmp+=d;
}
delete []strByte;
return changeHex(atmp).append(changeHex(btmp)).append(changeHex(ctmp)).append(changeHex(dtmp));
}
extern "C" nasal_ref nas_md5(std::vector<nasal_ref>& args,nasal_gc& gc){
if(!args.size())
return builtin_err("md5","lack arguments");
nasal_ref str=args[0];
if(str.type!=vm_str)
return builtin_err("md5","\"str\" must be a string");
nasal_ref res=gc.alloc(vm_str);
res.str()=md5(str.str());
return res;
}

View File

@ -227,7 +227,7 @@ void nasal_vm::stackinfo(const uint32_t limit=10)
printf("%ld):\n",top-bottom+1);
for(uint32_t i=0;i<limit && top>=bottom;++i,--top)
{
printf("0x%.8lx",top-gc.stack);
printf(" 0x%.8lx",top-gc.stack);
valinfo(top[0]);
}
}
@ -238,7 +238,7 @@ void nasal_vm::global_state()
printf("global(0x%lx<sp+0>):\n",(uint64_t)gc.stack);
for(uint32_t i=0;i<bytecode[0].num;++i)
{
printf("0x%.8x",i);
printf(" 0x%.8x",i);
valinfo(gc.stack[i]);
}
}
@ -250,7 +250,7 @@ void nasal_vm::local_state()
printf("local(0x%lx<sp+%ld>):\n",(uint64_t)localr,localr-gc.stack);
for(uint32_t i=0;i<lsize;++i)
{
printf("0x%.8x",i);
printf(" 0x%.8x",i);
valinfo(localr[i]);
}
}
@ -262,23 +262,23 @@ void nasal_vm::upval_state()
auto& upval=gc.funcr.func().upvalue;
for(uint32_t i=0;i<upval.size();++i)
{
printf("-> upval[%u]:\n",i);
printf(" -> upval[%u]:\n",i);
auto& uv=upval[i].upval();
for(uint32_t j=0;j<uv.size;++j)
{
printf(" 0x%.8x",j);
printf(" 0x%.8x",j);
valinfo(uv[j]);
}
}
}
void nasal_vm::detail()
{
printf("maddr(0x%lx)\n",(uint64_t)mem_addr);
printf("localr(0x%lx)\n",(uint64_t)localr);
printf("maddr:\n (0x%lx)\n",(uint64_t)mem_addr);
printf("localr:\n (0x%lx)\n",(uint64_t)localr);
if(gc.funcr.type==vm_nil)
printf("funcr(nil)\n");
printf("funcr:\n (nil)\n");
else
printf("funcr(<0x%lx> entry:0x%x)\n",
printf("funcr:\n (<0x%lx> entry:0x%x)\n",
(uint64_t)gc.funcr.value.gcobj,
gc.funcr.func().entry);
global_state();

View File

@ -1,90 +1,156 @@
import("lib.nas");
var check=func(x){
return x-int(x/0x100000000)*0x100000000;
}
var bits_and=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 and tmpy==1);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_or=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 or tmpy==1);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_xor=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx!=tmpy);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_not=func(x){
x=check(x);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
res+=op*((x-int(x/2)*2)==1?0:1);
x=int(x/2);
op*=2;
}
return res;
}
var hex32str=func(num){
var ch="0123456789abcdef";
var res="";
for(var i=0;i<4;i+=1){
var tmp="";
for(var j=0;j<2;j+=1){
tmp=chr(ch[bits_and(num,0x0f)])~tmp;
num=int(num/16);
}
res~=tmp;
}
return res;
}
var md5=func(s){
var K=[
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
];
var S=[
7,12,17,22,
7,12,17,22,
7,12,17,22,
7,12,17,22,
5,9,14,20,
5,9,14,20,
5,9,14,20,
5,9,14,20,
4,11,16,23,
4,11,16,23,
4,11,16,23,
4,11,16,23,
6,10,15,21,
6,10,15,21,
6,10,15,21,
6,10,15,21
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
];
var idx=[
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
];
var l=func(num,cx){
for(var i=0;i<cx;i+=1)
num=bits.bitand(0xffffffff,num*2);
for(var i=0;i<cx;i+=1){
num=check(num*2);
}
return num;
}
var r=func(num,cx){
for(var i=0;i<cx;i+=1)
num=int(num/2);
return num;
num=check(num);
for(var i=0;i<cx;i+=1){
num=num/2;
}
return int(num);
}
var rol=func(num,cx){
if(cx>32)
cx=cx-int(cx/32)*32;
return bits.bitor(l(num,cx),r(num,32-cx));
return bits_or(l(num,cx),r(num,32-cx));
}
# round 1
var F=func(x,y,z){
return bits.bitor(
bits.bitand(x,y),
bits.bitand(bits.bitnot(x),z)
return bits_or(
bits_and(x,y),
bits_and(bits_not(x),z)
);
}
# round 2
var G=func(x,y,z){
return bits.bitor(
bits.bitand(x,z),
bits.bitand(y,bits.bitnot(z))
return bits_or(
bits_and(x,z),
bits_and(y,bits_not(z))
);
}
# round 3
var H=func(x,y,z){
return bits.bitxor(bits.bitxor(x,y),z);
return bits_xor(bits_xor(x,y),z);
}
# round 4
var I=func(x,y,z){
return bits.bitor(
bits.bitxor(x,y),
bits.bitnot(z)
return bits_xor(
y,
bits_or(x,bits_not(z))
);
}
var len=size(s);
var len=size(s)*8;
var res=[];
var v=[256,128,64,32,16,8,4,2,1];
var v=[128,64,32,16,8,4,2,1];
for(var i=0;i<size(s);i+=1){
var c=s[i];
foreach(var j;v){
append(res,bits.bitand(c,j)?1:0);
}
}
# +------len------+--1~512--+--64--+
# | text | fill | size |
# +---------------+---------+------+ N*512
var mod=size(res)-int(size(res)/512)*512;
if(mod==0){
if(mod==448){
append(res,1);
mod+=1;
for(;mod<448;mod+=1)
for(var i=0;i<511;i+=1)
append(res,0);
}elsif(mod<448){
append(res,1);
@ -94,16 +160,105 @@ var md5=func(s){
}elsif(mod>448){
append(res,1);
mod+=1;
for(;mod<512+448;mod+=1)
# 512+448=960
for(;mod<960;mod+=1)
append(res,0);
}
var tmp=[];
var (tmp,cnt,t)=([],0,0);
foreach(var i;res){
if(!cnt)
t=i;
else
t=t*2+i;
cnt+=1;
if(cnt==8){
cnt=0;
append(tmp,t);
}
}
var A=0x01234567;
var B=0x89abcdef;
var C=0xfedcba98;
var D=0x76543210;
println(res,' ',size(res));
# little endian, this may have number overflow bug
# if the number is too large
var (lower32,higher32)=(check(len),check(len/math.pow(2,32)));
for(var i=0;i<4;i+=1){
append(tmp,int(lower32-int(lower32/256)*256));
lower32=int(lower32/256);
}
for(var i=0;i<4;i+=1){
append(tmp,int(higher32-int(higher32/256)*256));
higher32=int(higher32/256);
}
res=tmp;
# 1 block=>16 uint32=>64 byte=>512 bit
tmp=[];
for(var i=0;i<size(res);i+=4){
append(tmp,
res[i+3]*math.pow(2,24)+
res[i+2]*math.pow(2,16)+
res[i+1]*math.pow(2,8)+
res[i]
);
}
res=tmp;
var A=0x67452301;
var B=0xefcdab89;
var C=0x98badcfe;
var D=0x10325476;
for(var i=0;i<size(res);i+=16){
var (f,a,b,c,d)=(0,A,B,C,D);
for(var j=0;j<64;j+=1){
if(j<16){
f=F(b,c,d);
}elsif(j<32){
f=G(b,c,d);
}elsif(j<48){
f=H(b,c,d);
}else{
f=I(b,c,d);
}
var tmp=d;
d=c;
c=b;
b=check(b+rol(a+f+K[j]+res[idx[j]],S[j]));
a=tmp;
}
A=check(a+A);
B=check(b+B);
C=check(c+C);
D=check(d+D);
}
return hex32str(A)~hex32str(B)~hex32str(C)~hex32str(D);
}
md5("helloworld");
func(){
var test_set=[
"github.com",
"helloworld",
"abc",
"https://www.github.com/ValKmjolnir/Nasal-Interpreter",
"https://github.com/andyross/nasal",
"var (lower32,higher32)=(check(len),check(len/math.pow(2,32)));",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
];
var result=[
"99cd2175108d157588c04758296d1cfc",
"fc5e038d38a57032085441e7fe7010b0",
"900150983cd24fb0d6963f7d28e17f72",
"6b3a7bbc2240046c4fb1b0b3a4ed8181",
"14a6afca5f3a7b239c56b5a9678c428e",
"f499377c9ae8454c6c8a21ddba7f00de",
"fdacad297f72956e0619002cecffc8e3"
];
forindex(var i;test_set)
if(cmp(md5(test_set[i]),result[i]))
println(
"md5 cannot work:\n",
" test \""~test_set[i]~"\"\n",
" result \""~result[i]~"\"\n",
" but get \""~md5(test_set[i])~"\"\n"
);
}();