短网址的研究与实现Word格式文档下载.docx
《短网址的研究与实现Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《短网址的研究与实现Word格式文档下载.docx(27页珍藏版)》请在冰豆网上搜索。
短网址通常使用“比较少字符的网址”+“/”+“代码”,打开短网址网页通常会直接跳转到你要缩短的网址(常见),或者几秒广告后在跳转。
比如向XX短网址可以自定义后缀,有些短网址还可以进行泛域名解析,十分方便大家使用。
2短网址算法原理
1)将长网址md5生成32位签名串,分为4段,每段1个字节(即8位);
2)对这四段循环处理,取1个字节(8位),将他看成16进制串与0x3fffffff(30位1)与操作,即超过30位的忽略处理;
3)这30位分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;
4)总的md5串可以获得4个6位串;
取里面的任意一个就可作为这个长url的短url地址;
3md5简介
1991年,Rivest开发出技术上更为趋近成熟的md5算法。
它在MD4的基础上增加了"
安全-带子"
(safety-belts)的概念。
虽然MD5比MD4复杂度大一些,但却更为安全。
这个算法很明显的由四个和MD4设计有少许不同的步骤组成。
在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。
Denboer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。
4md5加密算法
对MD5算法简要的叙述可以为:
MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。
因此,信息的位长(BitsLength)将被扩展至N*512+448,N为一个非负整数,N可以是零。
填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。
然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。
经过这两步的处理,信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。
这样做的原因是为满足后面处理中对信息长度的要求。
总体流程如下图所示,
表示第i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。
初始的128位值为初试链接变量,这些参数用于第一轮的运算,以大端字节序来表示,他们分别为:
A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210。
每一分组的算法流程如下:
第一分组需要将上面四个链接变量复制到另外四个变量中:
A到a,B到b,C到c,D到d。
从第二分组开始的变量为上一分组的运算结果。
主循环有四轮(MD4只有三轮),每轮循环都很相似。
第一轮进行16次操作。
每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。
再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。
最后用该结果取代a、b、c或d中之一。
以下是每次操作中用到的四个非线性函数(每轮一个)。
F(X,Y,Z)=(X&
Y)|((~X)&
Z)
G(X,Y,Z)=(X&
Z)|(Y&
(~Z))
H(X,Y,Z)=X^Y^Z
I(X,Y,Z)=Y^(X|(~Z))
(&
;
是与,|是或,~是非,^是异或)
这四个函数的说明:
如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
F是一个逐位运算的函数。
即,如果X,那么Y,否则Z。
函数H是逐位奇偶操作符。
假设Mj表示消息的第j个子分组(从0到15),常数ti是4294967296*abs(sin(i))的整数部分,i取值从1到64,单位是弧度。
(4294967296等于2的32次方)
FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<
<
s)
GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<
HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<
Ⅱ(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<
这四轮(64步)是:
第一轮
FF(a,b,c,d,M0,7,0xd76aa478)
FF(d,a,b,c,M1,12,0xe8c7b756)
FF(c,d,a,b,M2,17,0x242070db)
FF(b,c,d,a,M3,22,0xc1bdceee)
FF(a,b,c,d,M4,7,0xf57c0faf)
FF(d,a,b,c,M5,12,0x4787c62a)
FF(c,d,a,b,M6,17,0xa8304613)
FF(b,c,d,a,M7,22,0xfd469501)
FF(a,b,c,d,M8,7,0x698098d8)
FF(d,a,b,c,M9,12,0x8b44f7af)
FF(c,d,a,b,M10,17,0xffff5bb1)
FF(b,c,d,a,M11,22,0x895cd7be)
FF(a,b,c,d,M12,7,0x6b901122)
FF(d,a,b,c,M13,12,0xfd987193)
FF(c,d,a,b,M14,17,0xa679438e)
FF(b,c,d,a,M15,22,0x49b40821)
第二轮
GG(a,b,c,d,M1,5,0xf61e2562)
GG(d,a,b,c,M6,9,0xc040b340)
GG(c,d,a,b,M11,14,0x265e5a51)
GG(b,c,d,a,M0,20,0xe9b6c7aa)
GG(a,b,c,d,M5,5,0xd62f105d)
GG(d,a,b,c,M10,9,0x02441453)
GG(c,d,a,b,M15,14,0xd8a1e681)
GG(b,c,d,a,M4,20,0xe7d3fbc8)
GG(a,b,c,d,M9,5,0x21e1cde6)
GG(d,a,b,c,M14,9,0xc33707d6)
GG(c,d,a,b,M3,14,0xf4d50d87)
GG(b,c,d,a,M8,20,0x455a14ed)
GG(a,b,c,d,M13,5,0xa9e3e905)
GG(d,a,b,c,M2,9,0xfcefa3f8)
GG(c,d,a,b,M7,14,0x676f02d9)
GG(b,c,d,a,M12,20,0x8d2a4c8a)
第三轮
HH(a,b,c,d,M5,4,0xfffa3942)
HH(d,a,b,c,M8,11,0x8771f681)
HH(c,d,a,b,M11,16,0x6d9d6122)
HH(b,c,d,a,M14,23,0xfde5380c)
HH(a,b,c,d,M1,4,0xa4beea44)
HH(d,a,b,c,M4,11,0x4bdecfa9)
HH(c,d,a,b,M7,16,0xf6bb4b60)
HH(b,c,d,a,M10,23,0xbebfbc70)
HH(a,b,c,d,M13,4,0x289b7ec6)
HH(d,a,b,c,M0,11,0xeaa127fa)
HH(c,d,a,b,M3,16,0xd4ef3085)
HH(b,c,d,a,M6,23,0x04881d05)
HH(a,b,c,d,M9,4,0xd9d4d039)
HH(d,a,b,c,M12,11,0xe6db99e5)
HH(c,d,a,b,M15,16,0x1fa27cf8)
HH(b,c,d,a,M2,23,0xc4ac5665)
第四轮
Ⅱ(a,b,c,d,M0,6,0xf4292244)
Ⅱ(d,a,b,c,M7,10,0x432aff97)
Ⅱ(c,d,a,b,M14,15,0xab9423a7)
Ⅱ(b,c,d,a,M5,21,0xfc93a039)
Ⅱ(a,b,c,d,M12,6,0x655b59c3)
Ⅱ(d,a,b,c,M3,10,0x8f0ccc92)
Ⅱ(c,d,a,b,M10,15,0xffeff47d)
Ⅱ(b,c,d,a,M1,21,0x85845dd1)
Ⅱ(a,b,c,d,M8,6,0x6fa87e4f)
Ⅱ(d,a,b,c,M15,10,0xfe2ce6e0)
Ⅱ(c,d,a,b,M6,15,0xa3014314)
Ⅱ(b,c,d,a,M13,21,0x4e0811a1)
Ⅱ(a,b,c,d,M4,6,0xf7537e82)
Ⅱ(d,a,b,c,M11,10,0xbd3af235)
Ⅱ(c,d,a,b,M2,15,0x2ad7d2bb)
Ⅱ(b,c,d,a,M9,21,0xeb86d391)
所有这些完成之后,将A、B、C、D分别加上a、b、c、d。
然后用下一分组数据继续运行算法,最后的输出是A、B、C和D的级联。
三、算法流程图
Md5加密
生成短网址还原长网址
四、过程及结果
生成短网址
还原短网址
Txt中存储内容
五、设计总结
本次实验主要完成了短网址的生成与实现,在实现过程中,使用java或者php可能会比较简单实现,但是因为没有学过这类语言所以使用了C++的实现方法,在实验过程中,碰到了一些瓶颈,在string类型做运算时碰到了困难,在同学的帮助下转换成了int类型数组进行了与运算,将英文字母转化成对应的数字进行计算,使用md5的值将长网址成功简化成短网址,在简化过程中应该将对应的数据录入数据库,因为之前没有使用过C++连接数据库的经验,在网络和图书馆也没有找到相关资料,最后选择使用文件流将其输入TXT文档中,在将短网址还原到长网址的过程中,检索对应的5位短网址,因为输入时是用空行排列,所以一旦找到对应短网址读取下一行就是对应的长网址了。
对于本次实验,查了很多资料,学习了md5加密算法的流程,并且将实现的过程也了解了一下,对于短网址,已经是现在的主流,很多地方都能用到,之前从来没有想过这个短网址生成的方法,通过实验详细了解了也亲手实践,体会到了这一个转化的过程,对于整个完成的实验,总的来说还是有所不足,对于数据类型的把握和数据文件的处理方面还有所欠缺。
六、源程序
Md5.h
#ifndefMD5_H
#defineMD5_H
#include<
string>
fstream>
/*Typedefine*/
typedefunsignedcharbyte;
typedefunsignedlongulong;
usingstd:
:
string;
ifstream;
/*MD5declaration.*/
classMD5{
public:
MD5();
MD5(constvoid*input,size_tlength);
MD5(conststring&
str);
MD5(ifstream&
in);
voidupdate(constvoid*input,size_tlength);
voidupdate(conststring&
voidupdate(ifstream&
constbyte*digest();
stringtoString();
voidreset();
private:
voidupdate(constbyte*input,size_tlength);
voidfinal();
voidtransform(constbyteblock[64]);
voidencode(constulong*input,byte*output,size_tlength);
voiddecode(constbyte*input,ulong*output,size_tlength);
stringbytesToHexString(constbyte*input,size_tlength);
/*classuncopyable*/
MD5(constMD5&
);
MD5&
operator=(constMD5&
ulong_state[4];
/*state(ABCD)*/
ulong_count[2];
/*numberofbits,modulo2^64(low-orderwordfirst)*/
byte_buffer[64];
/*inputbuffer*/
byte_digest[16];
/*messagedigest*/
bool_finished;
/*calculatefinished?
*/
staticconstbytePADDING[64];
/*paddingforcalculate*/
staticconstcharHEX[16];
};
#endif/*MD5_H*/
Md5.cpp
#include"
md5.h"
usingnamespacestd;
staticconstsize_tBUFFER_SIZE=1024;
/*ConstantsforMD5Transformroutine.*/
#defineS117
#defineS1212
#defineS1317
#defineS1422
#defineS215
#defineS229
#defineS2314
#defineS2420
#defineS314
#defineS3211
#defineS3316
#defineS3423
#defineS416
#defineS4210
#defineS4315
#defineS4421
/*F,G,HandIarebasicMD5functions.
*/
#defineF(x,y,z)(((x)&
(y))|((~x)&
(z)))
#defineG(x,y,z)(((x)&
(z))|((y)&
(~z)))
#defineH(x,y,z)((x)^(y)^(z))
#defineI(x,y,z)((y)^((x)|(~z)))
/*ROTATE_LEFTrotatesxleftnbits.
#defineROTATE_LEFT(x,n)(((x)<
(n))|((x)>
>
(32-(n))))
/*FF,GG,HH,andIItransformationsforrounds1,2,3,and4.
Rotationisseparatefromadditiontopreventrecomputation.
#defineFF(a,b,c,d,x,s,ac){\
(a)+=F((b),(c),(d))+(x)+ac;
\
(a)=ROTATE_LEFT((a),(s));
(a)+=(b);
}
#defineGG(a,b,c,d,x,s,ac){\
(a)+=G((b),(c),(d))+(x)+ac;
#defineHH(a,b,c,d,x,s,ac){\
(a)+=H((b),(c),(d))+(x)+ac;
#defineII(a,b,c,d,x,s,ac){\
(a)+=I((b),(c),(d))+(x)+ac;
constbyteMD5:
PADDING[64]={0x80};
constcharMD5:
HEX[16]={
'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
a'
b'
c'
d'
e'
f'
/*Defaultconstruct.*/
MD5:
MD5(){
reset();
/*ConstructaMD5objectwithainputbuffer.*/
MD5(constvoid*input,size_tlength){
update(input,length);
/*ConstructaMD5objectwithastring.*/
MD5(conststring&
str){
update(str);
/*ConstructaMD5objectwithafile.*/
MD5(ifstream&
in){
update(in);
/*Returnthemessage-digest*/
constbyte*MD5:
digest(){
if(!
_finished){
_finished=true;
final();
}
return_digest;
/*Resetthecalculatestate*/
voidMD5:
reset(){
_finished=false;
/*resetnumberofbits.*/
_count[0]=_count[1]=0;
/*Loadmagicinitializationconstants.*/
_state[0]=0x67452301;
_state[1]=0xefcdab89;
_state[2]=0x98badcfe;
_state[3]=0x10325476;
/*Updatingthecontextwithainputbuffer.*/
update(constvoid*input,size_tlength){
update((constbyte*)input,length);
/*Updatingthecontextwithastring.*/
update(conststring&
update((constbyte*)str.c_str(),str.length());
/*Updatingthecontextwithafile.*/
update(ifstream&
in)
return;
std:
streamsizelength;
charbuffer[BUFFER_SIZE];
while(!
in.eof()){
in.read(buffer,BUFFER_SIZE);
length=in.gcount();
if(length>
0)
update(buffer,length);
in.close();
/*MD5blockupdateoperation.ContinuesanMD5message-digest
operation,processinganothermessageblock,andupdatingthe
context.
update(constbyte*input,size_tlength){
ulongi,index,partLen;
/*Computenumberofbytesmod64*/
index=(ulong)((_count[0]>
3)&
0x3f);
/*updatenumberofbits*/
if((_count[0]+=((ulong)length<
3))<
((ulong)length<
3))
_count[1]++;
_count[1]+=((ulong)length>
29);
partLen=64-index;
/*transformasmanytimesaspossible.*/
if(length>
=partLen){
memcpy(&
_buffer[index],input,partLen);
transform(_buffer);
for(i=partLen;
i+63<
length;
i+=64)
transform(&
inp