optimize libmd5.nas & test/md5.nas

This commit is contained in:
ValKmjolnir 2022-04-03 18:10:00 +08:00
parent 92b684624d
commit a2b51fe212
4 changed files with 157 additions and 135 deletions

View File

@ -124,7 +124,7 @@ in __`linux/macOS/Unix`__:
## __How to Use__ ## __How to Use__
First we should learn how to write a program using this language, First we should learn how to write and run a program using this language,
click to see the [__tutorial__](#tutorial). click to see the [__tutorial__](#tutorial).
Input this command to run scripts __directly__: Input this command to run scripts __directly__:
@ -184,6 +184,13 @@ If your system is __`Windows`__ and you want to output unicode,please use this c
> chcp 65001 > chcp 65001
or you could write this in your nasal code:
```javascript
if(os.platform()=="windows")
system("chcp 65001");
```
## __Tutorial__ ## __Tutorial__
Nasal is really __easy__ to learn. Nasal is really __easy__ to learn.

View File

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

View File

@ -1,44 +1,39 @@
import("lib.nas"); import("lib.nas");
var check=func(x){ var check=func(x){
if(x<0x100000000)
return x;
return x-int(x/0x100000000)*0x100000000; return x-int(x/0x100000000)*0x100000000;
} }
var u32_bits_and=func(x,y){ var u32_bits_and=func(x,y){
x=check(x); (x,y)=(check(x),check(y));
y=check(y);
var (res,op)=(0,1); var (res,op)=(0,1);
for(var i=0;i<32;i+=1){ for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 and tmpy==1); res+=op*(tmpx==1 and tmpy==1);
x=int(x/2); (x,y)=(int(x/2),int(y/2));
y=int(y/2);
op*=2; op*=2;
} }
return res; return res;
} }
var u32_bits_or=func(x,y){ var u32_bits_or=func(x,y){
x=check(x); (x,y)=(check(x),check(y));
y=check(y);
var (res,op)=(0,1); var (res,op)=(0,1);
for(var i=0;i<32;i+=1){ for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 or tmpy==1); res+=op*(tmpx==1 or tmpy==1);
x=int(x/2); (x,y)=(int(x/2),int(y/2));
y=int(y/2);
op*=2; op*=2;
} }
return res; return res;
} }
var u32_bits_xor=func(x,y){ var u32_bits_xor=func(x,y){
x=check(x); (x,y)=(check(x),check(y));
y=check(y);
var (res,op)=(0,1); var (res,op)=(0,1);
for(var i=0;i<32;i+=1){ for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx!=tmpy); res+=op*(tmpx!=tmpy);
x=int(x/2); (x,y)=(int(x/2),int(y/2));
y=int(y/2);
op*=2; op*=2;
} }
return res; return res;
@ -54,22 +49,25 @@ var u32_bits_not=func(x){
return res; return res;
} }
var hex32str=func(num){ var hex32str=func(){
var ch=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]; var ch=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
var res=""; var tbl=[];
for(var i=0;i<4;i+=1){ setsize(tbl,256);
var tmp=""; for(var i=0;i<16;i+=1){
for(var j=0;j<2;j+=1){ for(var j=0;j<16;j+=1)
tmp=ch[u32_bits_and(num,0x0f)]~tmp; tbl[i*16+j]=ch[i]~ch[j];
num=int(num/16);
}
res~=tmp;
} }
return res; return func(num){
} var res="";
for(var i=0;i<4;i+=1){
var _md5=func(s){ res~=tbl[u32_bits_and(num,0xff)];
num=int(num/256);
}
return res;
};
}();
var _md5=func(){
var K=[ var K=[
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
@ -135,92 +133,105 @@ var _md5=func(s){
u32_bits_or(x,u32_bits_not(z)) u32_bits_or(x,u32_bits_not(z))
); );
} }
var functions=[
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,
H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I
];
var len=size(s)*8; return func(s){
var res=[]; var len=size(s)*8;
setsize(res,len); var res=[];
var v=[128,64,32,16,8,4,2,1]; setsize(res,len);
for(var i=0;i<size(s);i+=1){ for(var i=0;i<size(s);i+=1){
var c=s[i]; var c=s[i];
for(var j=0;j<8;j+=1){ var v=128;
res[i*8+j]=(bits.bitand(c,v[j])?1:0); for(var j=0;j<8;j+=1){
res[i*8+j]=(bits.bitand(c,v)?1:0);
v=int(v/2);
}
} }
} # +------len------+--1~512--+--64--+
# +------len------+--1~512--+--64--+ # | text | fill | size |
# | text | fill | size | # +---------------+---------+------+ N*512
# +---------------+---------+------+ N*512 var mod=size(res)-int(size(res)/512)*512;
var mod=size(res)-int(size(res)/512)*512; if(mod==448){
if(mod==448){ var i=size(res);
append(res,1); setsize(res,i+512);
for(var i=0;i<511;i+=1) res[i]=1;
append(res,0); for(i+=1;i<size(res);i+=1)
}elsif(mod<448){ res[i]=0;
append(res,1); }elsif(mod<448){
mod+=1; var i=size(res);
for(;mod<448;mod+=1) setsize(res,int(i/512)*512+448);
append(res,0); res[i]=1;
}elsif(mod>448){ for(i+=1;i<size(res);i+=1)
append(res,1); res[i]=0;
mod+=1; }elsif(mod>448){
# 512+448=960 var i=size(res);
for(;mod<960;mod+=1) setsize(res,int(i/512)*512+960); # 512+448=960
append(res,0); res[i]=1;
} for(i+=1;i<size(res);i+=1)
var (tmp,cnt,t)=([],0,0); res[i]=0;
foreach(var i;res){
if(!cnt) t=i;
else t=t*2+i;
cnt+=1;
if(cnt==8){
cnt=0;
append(tmp,t);
} }
}
# little endian, this may have number overflow bug # translate bits to bytes and reserve 64bit space for string length
# if the number is too large var (tmp,cnt,t,index)=([],0,0,0);
var (lower32,higher32)=(check(len),check(len/math.pow(2,32))); setsize(tmp,int(size(res)/8)+8);
for(var i=0;i<4;i+=1){ foreach(var i;res){
append(tmp,int(lower32-int(lower32/256)*256)); if(!cnt) t=i;
lower32=int(lower32/256); else t=t*2+i;
} cnt+=1;
for(var i=0;i<4;i+=1){ if(cnt==8){
append(tmp,int(higher32-int(higher32/256)*256)); tmp[index]=t;
higher32=int(higher32/256); index+=1;
} cnt=0;
res=tmp; }
# 1 block=>16 uint32=>64 byte=>512 bit
# because using double to discribe number
# this may only work when string's length is under 1<<51
tmp=[];
setsize(tmp,size(res)/4);
for(var i=0;i<size(res);i+=4){
tmp[i/4]=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);
(a,b,c,d)=(d,check(b+rol(a+f+K[j]+res[i+idx[j]],S[j])),b,c);
} }
(A,B,C,D)=(check(a+A),check(b+B),check(c+C),check(d+D));
} # little endian, this may have number overflow bug
return hex32str(A)~hex32str(B)~hex32str(C)~hex32str(D); # if the number is too large
} var (tmp_size,lower32,higher32)=(size(tmp),check(len),check(len/math.pow(2,32)));
for(var i=4;i>0;i-=1){
tmp[tmp_size-4-i]=int(lower32-int(lower32/256)*256);
lower32=int(lower32/256);
}
for(var i=4;i>0;i-=1){
tmp[tmp_size-i]=int(higher32-int(higher32/256)*256);
higher32=int(higher32/256);
}
res=tmp;
# 1 block=>16 uint32=>64 byte=>512 bit
# because using double to discribe number
# this may only work when string's length is under 1<<51
tmp=[];
setsize(tmp,size(res)/4);
for(var i=0;i<size(res);i+=4){
tmp[i/4]=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){
f=functions[j](b,c,d);
(a,b,c,d)=(d,check(b+rol(a+f+K[j]+res[i+idx[j]],S[j])),b,c);
}
(A,B,C,D)=(check(a+A),check(b+B),check(c+C),check(d+D));
}
return hex32str(A)~hex32str(B)~hex32str(C)~hex32str(D);
};
}();
# check if md5 runs correctly # check if md5 runs correctly
var md5check=func(){ var md5check=func(){

View File

@ -4,34 +4,36 @@ import("test/md5.nas");
rand(time(0)); rand(time(0));
var compare=func(total){ var compare=func(){
var ch=[ var ch=[
"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","+", "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","+",
"_","*","/","\'","\"",".",",",";",":","<",">","!","@","#","$","%", "_","*","/","\'","\"",".",",",";",":","<",">","!","@","#","$","%",
"^","&","*","(",")","-","=","\\","|","[","]","{","}","`"," ","\t","?" "^","&","*","(",")","-","=","\\","|","[","]","{","}","`"," ","\t","?"
]; ];
var (prt,lastpercent,percent)=("",0,0); return func(total){
for(var i=1;i<=total;i+=1){ var (prt,lastpercent,percent)=("",0,0);
var s=""; for(var i=1;i<=total;i+=1){
for(var j=0;j<i;j+=1){ var s="";
s~=ch[rand()*size(ch)]; for(var j=0;j<i;j+=1){
s~=ch[rand()*size(ch)];
}
var res=md5(s);
if(cmp(res,_md5(s))){
die("error: "~str(i));
}
percent=int(i/total*100);
if(percent-lastpercent>=2){
prt~="#";
lastpercent=percent;
}
var tmp=prt;
for(var spc=size(prt);spc<50;spc+=1)
tmp~=" ";
print(" |",tmp,"| ",percent,"% (",i,"/",total,")\t",res," \r");
} }
var res=md5(s); print('\n');
if(cmp(res,_md5(s))){ };
die("error: "~str(i)); }();
}
percent=int(i/total*100);
if(percent-lastpercent>=2){
prt~="#";
lastpercent=percent;
}
var tmp=prt;
for(var spc=size(prt);spc<50;spc+=1)
tmp~=" ";
print(" |",tmp,"| ",percent,"% (",i,"/",total,")\t",res," \r");
}
print('\n');
}
var filechecksum=func(){ var filechecksum=func(){
var getname=func(s){ var getname=func(s){