给作业加个数字签名
当了数据结构的助教,还要修改作业。在学生们的作业本上留下了对错号。但是没有写其他的东西。为了防止有学生来冒充我的笔迹来自行打对错号,然后声称没有给分这种现象
的发生。我花了一个小时做了一个数字签名。因为我的笔迹很烂,很容易模仿。
代码如下:基本原理使用的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函数是如何去写的。因为我也不清楚为什
么这样写。
以后改作业可以省心了。