当了数据结构的助教,还要修改作业。在学生们的作业本上留下了对错号。但是没有写其他的东西。为了防止有学生来冒充我的笔迹来自行打对错号,然后声称没有给分这种现象的发生。我花了一个小时做了一个数字签名。因为我的笔迹很烂,很容易模仿。
代码如下:基本原理使用的Hash散列。所以不知道签名数据的人,绝对可能从自己作业的签名中获取签名数据,自然也不可能去冒充一个签名。
我使用的mysql的散列函数
#include"stdafx.h"
#include<iostream>
#include<string>

usingnamespacestd;

intiHTLen;

//mySqlhash
unsignedintHash(constchar*keys,constintlen)

...{
constchar*key=keys;
//Hashfunctionforcharacterkeys
intlength=len;
intnr=1,nr2=4;
while(length--)

...{
nr^=(((nr&63)+nr2)*(*key++))+(nr<<8);
nr2+=3;
}
return((unsignedint)nr)%iHTLen;
}

//justTesttheconsequencearecorrectornot
boolTestHashValue(constunsignedinthashValue[],intlen)

...{
for(inti=0;i<len;i++)

...{
for(intj=i+1;j<len;j++)

...{
if(hashValue[i]==hashValue[j])

...{
returnfalse;
}
}
}
returntrue;
}

//guaranteetheinputvaluesarenotthesame
boolTestPreValue(conststringstudents[],intlen)

...{
for(inti=0;i<len;i++)

...{
for(intj=i+1;j<len;j++)

...{
if(students[i]==students[j])

...{
returnfalse;
}
}
}
returntrue;
}

unsignedintHash(stringstudentName,stringdate,stringsigner)

...{
intlen=studentName.length()+date.length()+signer.length();
char*sign=newchar[len];
memset(sign,0,len);
strcpy(sign,studentName.c_str());
strcat(sign,date.c_str());
strcat(sign,signer.c_str());

returnHash(sign,len);

}


int_tmain(intargc,_TCHAR*argv[])

...{

intnum=0;
cin>>num;
string*students=newstring[num];
stringsignName;
stringdate;

for(inti=0;i<num;i++)

...{
cin>>students[i];
}

cin>>date;
cin>>signName;
cin>>iHTLen;
boolisGoon=TestPreValue(students,num);
if(!isGoon)

...{
cout<<"students'namesarethesame?"<<endl;
exit(2);
}

unsignedint*signNum=newunsignedint[num];
for(inti=0;i<num;i++)

...{
signNum[i]=Hash(students[i],signName,date);
}

boolisSuccess=TestHashValue(signNum,num);
if(!isSuccess)

...{
cout<<"pleasechangethelastvalueandrunagain!"<<endl;
exit(2);
}

for(inti=0;i<num;i++)

...{
cout<<students[i]<<" "<<signNum[i]<<endl;
}

return0;
}
幸好没有重名的学生。(*^__^*) 嘻嘻……
以上的代码使用VS2005的编译器。不过数据不方便透露,所以大家看懂代码可以自己输入自己的签名数据。大家不必在意Hash函数是如何去写的。因为我也不清楚为什么这样写。
以后改作业可以省心了。