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

#include  "  stdafx.h  "

#include  < iostream  >

#include  < string  >


using  namespace  std;


int  iHTLen;

 //
 //
mySql hash

unsigned  int  Hash (  const  char  *  keys,  const  int  len)
  …  {

const  char  *  key  =  keys;

//  Hash function for character keys

int  length  =  len;

int  nr  =  1  , nr2  =  4  ;

while  (length  --  )
  …  {

nr  ^=  (((nr  & 63  )  +  nr2)  *  (  *  key  ++  ))  +  (nr  << 8  );

nr2  +=  3  ;
 }

return  ((unsigned  int  ) nr)  %  iHTLen;
 }

 //
 //
just Test the consequence are correct or not

bool  TestHashValue(  const  unsigned  int  hashValue[],  int  len)
  …  {

for  (  int  i  =  0  ; i  < len; i  ++  )
  …  {

for  (  int  j  =  i  +  1  ; j  < len; j  ++  )
  …  {

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

return  false  ;
 }
 }
 }

return  true  ;
 }

 //
 //
guarantee the input values are not the same

bool  TestPreValue(  const  string  students[],  int  len)
  …  {

for  (  int  i  =  0  ; i  < len; i  ++  )
  …  {

for  (  int  j  =  i  +  1  ; j  < len; j  ++  )
  …  {

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

return  false  ;
 }
 }
 }

return  true  ;
 }


unsigned  int  Hash(  string  studentName,  string  date,  string  signer)
  …  {

int  len  =  studentName.length()  +  date.length()  +  signer.length();

char  *  sign  =  new  char  [len];

memset(sign,  0  ,len);

strcpy(sign,studentName.c_str());

strcat(sign,date.c_str());

strcat(sign,signer.c_str());


return  Hash(sign,len);

 }



int  _tmain(  int  argc, _TCHAR  *  argv[])
  …  {


int  num  =  0  ;

cin  >> num;

string  *  students  =  new  string  [num];

string  signName;

string  date;


for  (  int  i  =  0  ; i  < num; i  ++  )
  …  {

cin  >> students[i];
 }


cin  >> date;

cin  >> signName;

cin  >> iHTLen;

bool  isGoon  =  TestPreValue(students,num);

if  (  !  isGoon)
  …  {

cout  << "  students’ names are the same?  "  << endl;

exit(  2  );
 }


unsigned  int  *  signNum  =  new  unsigned  int  [num];

for  (  int  i  =  0  ; i  < num; i  ++  )
  …  {

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


bool  isSuccess  =  TestHashValue(signNum,num);

if  (  !  isSuccess)
  …  {

cout  << "  please change the last value and run again!  "  << endl;

exit(  2  );
 }


for  (  int  i  =  0  ; i  < num; i  ++  )
  …  {

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


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