strlen计算长度hello/t/0///为多少?6吗?还是5

Keyboard Shortcuts?
Next menu item
Previous menu item
Previous man page
Next man page
Scroll to bottom
Scroll to top
Goto homepage
Goto search(current page)
Focus search box
Change language:
Brazilian Portuguese
Chinese (Simplified)
str_pad & 使用另一个字符串填充字符串为指定长度
string str_pad
( string $input
, int $pad_length
[, string $pad_string = & &
[, int $pad_type = STR_PAD_RIGHT
输入字符串。
pad_length
如果 pad_length 的值是负数,小于或者等于输入字符串的长度,不会发生任何填充,并会返回 input 。
pad_string
如果填充字符的长度不能被 pad_string 整除,那么 pad_string 可能会被缩短。
可选的 pad_type 参数的可能值为 STR_PAD_RIGHT,STR_PAD_LEFT 或 STR_PAD_BOTH。如果没有指定 pad_type,则假定它是 STR_PAD_RIGHT。
返回填充后的字符串。
Example #1 str_pad() 范例
&?php$input&=&"Alien";echo&str_pad($input,&10);&&&&&&&&&&&&&&&&&&&&&&//&输出&"Alien&&&&&"echo&str_pad($input,&10,&"-=",&STR_PAD_LEFT);&&//&输出&"-=-=-Alien"echo&str_pad($input,&10,&"_",&STR_PAD_BOTH);&&&//&输出&"__Alien___"echo&str_pad($input,&&6,&"___");&&&&&&&&&&&&&&&//&输出&"Alien_"echo&str_pad($input,&&3,&"*");&&&&&&&&&&&&&&&&&//&输出&"Alien"?&
since the default pad_type is STR_PAD_RIGHT. using STR_PAD_BOTH were always favor in the right pad if the required number of padding characters can't be evenly divided. e.g&?phpecho str_pad("input", 10, "pp", STR_PAD_BOTH ); echo str_pad("input", 6, "p", STR_PAD_BOTH ); echo str_pad("input", 8, "p", STR_PAD_BOTH ); ?&
A proper u&?phpmb_internal_encoding('utf-8'); function str_pad_unicode($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT) {& & $str_len = mb_strlen($str);& & $pad_str_len = mb_strlen($pad_str);& & if (!$str_len && ($dir == STR_PAD_RIGHT || $dir == STR_PAD_LEFT)) {& & & & $str_len = 1; }& & if (!$pad_len || !$pad_str_len || $pad_len &= $str_len) {& & & & return $str;& & }& & & & $result = null;& & $repeat = ceil($str_len - $pad_str_len + $pad_len);& & if ($dir == STR_PAD_RIGHT) {& & & & $result = $str . str_repeat($pad_str, $repeat);& & & & $result = mb_substr($result, 0, $pad_len);& & } else if ($dir == STR_PAD_LEFT) {& & & & $result = str_repeat($pad_str, $repeat) . $str;& & & & $result = mb_substr($result, -$pad_len);& & } else if ($dir == STR_PAD_BOTH) {& & & & $length = ($pad_len - $str_len) / 2;& & & & $repeat = ceil($length / $pad_str_len);& & & & $result = mb_substr(str_repeat($pad_str, $repeat), 0, floor($length)) & & & & & & & & & & . $str & & & & & & & & & & && . mb_substr(str_repeat($pad_str, $repeat), 0, ceil($length));& & }& & & & return $result;}?&T&?php$s = '...';for ($i = 3; $i &= 1000; $i++) {& & $s1 = str_pad($s, $i, 'AO', STR_PAD_BOTH); $s2 = str_pad_unicode($s, $i, '??', STR_PAD_BOTH);& & $sl1 = strlen($s1);& & $sl2 = mb_strlen($s2);& & echo& "len $sl1: $s1 \n";& & echo& "len $sl2: $s2 \n";& & echo& "\n";& & if ($sl1 != $sl2) die("Fail!");}?&Olen 3: ... len 3: ... len 4: ...A len 4: ...? len 5: A...A len 5: ?...? len 6: A...AO len 6: ?...?? ...
For me this worked.$string = 'help';#First, str_pad() with unique character.$string = str_pad($string, 10, "*", STR_PAD_BOTH);#$string = '***help***';#Second, str_replace with '&'$string = str_replace("*", "&", $string);
multibyte version:&?phpfunction mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL){& & $encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;& & $padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;& & $padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;& & $pad_len -= mb_strlen($str, $encoding);& & $targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;& & $strToRepeatLen = mb_strlen($pad_str, $encoding);& & $repeatTimes = ceil($targetLen / $strToRepeatLen);& & $repeatedString = str_repeat($pad_str, max(0, $repeatTimes)); $before = $padBefore ? mb_substr($repeatedString, 0, floor($targetLen), $encoding) : '';& & $after = $padAfter ? mb_substr($repeatedString, 0, ceil($targetLen), $encoding) : '';& & return $before . $str . $after;}?&
Fills the first argument (mostly a number, f.e. from a &select& loop to display a date or time) with zeroes.&?phpfunction zerofill($mStretch, $iLength = 2){& & $sPrintfString = '%0' . (int)$iLength . 's';& & return sprintf($sPrintfString, $mStretch);}?&sprintf() is indeed faster than str_pad.
a different, more robust multibyte version of str_pad that works correctly only if $pad_string is non-multibyte stringfunction my_mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){& & $mb_diff=mb_strlen($str, $encoding)-strlen($string);& & & & & & return str_pad($input,$pad_length+$mb_diff,$pad_string,$pad_type);}
In case you want to pad 2 strings together with a character you can use:&?phpfunction pad_between_strings($string1, $string2, $length, $char = " ") {& & $fill_length = $length - ( strlen($string1) + strlen($string2) );& & return $string1 . str_repeat($char, $fill_length) . $string2;}?&
In a lot of cases you're better off using str_repeat if you want to use something like&& - it repeats the entire string.
Using str_repeat, I wrote a full string pad function that should closely mimic str_pad in every other way:
&?php
function full_str_pad($input, $pad_length, $pad_string = '', $pad_type = 0) {
$str = '';
$length = $pad_length - strlen($input);
if ($length & 0) { if ($pad_type == STR_PAD_RIGHT) { $str = $input.str_repeat($pad_string, $length);
& } elseif ($pad_type == STR_PAD_BOTH) { $str = str_repeat($pad_string, floor($length/2));
&& $str .= $input;
&& $str .= str_repeat($pad_string, ceil($length/2));
& } else { $str = str_repeat($pad_string, $length).$input;
& }
} else { $str = $input;
return $str;
}
$pad_me = "Test String";
echo '|'.full_str_pad($pad_me, 20, ' ')."|\n";
echo '|'.full_str_pad($pad_me, 20, ' ', STR_PAD_RIGHT)."|\n";
echo '|'.full_str_pad($pad_me, 20, ' ', STR_PAD_BOTH)."|\n";
?&
Warning: If your string includes non-ascii characters (eg the British pounds sign), str_pad() will treat these as two characters when calculating the padding.So for example:&?phpstr_pad($currency_symbol.$showtottopay,12," ",STR_PAD_LEFT);?&will produce a different length string depending on whether $currency_symbol is pounds or dollars.Hope this helps someone -- it caused me a lot of problems with misaligned columns in my invoices until I worked it out.
Basically, *all* of you guys have a 'long' way of padding text with html tags (which includes &) You dont even have to do a str_replace... try the following code and this will work with ANY html tag there is out there and you don't have to worry about tag character lengths so on and so forth:&?& $text = "This is pretty interesting!";& $pad_string = "&";& & //Pad text on both sides & $text = str_pad($text, strlen($text)+(20*strlen($pad_string)), $pad_string, STR_PAD_BOTH);& print $text." Dont you think?";?&Will produce:& & & & & This is pretty interesting!& & & & && Dont you think?Cheers,Fahad
sprintf() is not always faster... It certainly scales a lot better then str_pad so when running a benchmark that pads 10k characters,& sprintf will come out on top. But if you benchmarked a more real world scenario, it seems str_pad comes out the clear winner.$sTime = microtime(true);$count = 5;$s = sprintf("%'\n5s", "\n");$eTime = microtime(true);echo 'sprintf ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";$sTime = microtime(true);$s = str_pad("\n", 5, "\n");$eTime = microtime(true);echo 'str_pad ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";sprintf ran in 0.805 millisecondsstr_pad ran in 0.5391 milliseconds
sprintf is faster$sTime = microtime(true);$s = sprintf("%'-1000000s", '-');$eTime = microtime(true);echo 'sprintf ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";$sTime = microtime(true);$s = str_pad('-', 1000000, '-');$eTime = microtime(true);echo 'str_pad ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";//resultsprintf ran in 2.1 millisecondsstr_pad ran in 26. milliseconds
Here is the mcinp's version of mb_str_pad bugfixed: &?phpfunction mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){& & & & $mb_diff=mb_strlen($input, $encoding)-strlen($input);& & & & return str_pad($input,$pad_length-$mb_diff,$pad_string,$pad_type);& & } ?& Still working correctly only if $pad_string is non-multibyte string
This is how I pad using & :str_replace(" ", "&&", str_pad($foo, 10, " ", STR_PAD_LEFT))Seems to work well using two & tags for each character added, at least for my use. YMMV.
// Columnizer: add padding into text columns according maximum column size.// sample input:$a='[1515] -& ID=1515 / post_date= 04:48:47 / post_name=review-terminatrix-by-sfam & & [177] -& ID=177 / post_date= 12:12:03 / post_name=review-the-terminator-by-sfam & & [] -& ID=2286 / post_date= 04:48:32 / post_name=terminator-3-rise-of-the-machines-2003';function columnize($input, $separator=" "){& & $lines = explode("\n", $input);& & foreach ($lines as $k=&$line){& & & $r[$k] = explode(" ", trim($line));& & }& & // print_r($r);& & $nc = sizeOf($r[0]);& & // echo $& & for($i=0;$i&$$i++){& & & $col[$i] = array_column($r, $i);& & & }& & // print_r($col);& & for ($i=0;$i&sizeof($col);$i++){& & & $maxlen = max(array_map('strlen', $col[$i]));& & & $tam[$i]=$& & & // echo "$i:$maxlen".PHP_EOL;& & & $cs[$i]=$& & }& & // print_r($cs);& & $o="";& & for ($r=0;$r&sizeOf($lines);$r++){& & & for ($c=0;$c&sizeof($cs);$c++){& & & & $o.= str_pad($col[$c][$r], $cs[$c]+2, " ", STR_PAD_RIGHT );& & & }& & & $o .= PHP_EOL;& & }& & & & return $o;& }echo $columnize($a);// will output text nicely in columns :)
Here's a quick and simple way to make an mb_str_pad function that works when you have correctly set your internal encoding.I'm not sure how well this works in all possible scenarios but atleast it worked for me using UTF-8 as internal encoding and using this function on strings containing scandinavian characters "??????" that are double byte in UTF-8.&?phpfunction mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT) {& & $diff = strlen($input) - mb_strlen($input);& & return str_pad($input, $pad_length+$diff, $pad_string, $pad_type);}?&
for anyone who needs this, I wrote this extension to str_pad. For details, just look at the comments.
$string = 'this is a test';
$oldLen = strlen($string);
$direction = STR_PAD_BOTH;
echo $string.'&br&';
echo str_const_len($string, 101, '#', $direction).'&br&';
echo $string.'&br&';
echo str_const_len($string, $oldLen, '#', $direction).'&br&';
echo $string.'&br&&br&'."\n";
function str_const_len(&$str, $len, $char = ' ', $str_pad_const = STR_PAD_RIGHT) {
& & $origLen = strlen($str);
& & if (strlen($str) & $len) {& && $str = str_pad($str, $len, $char, $str_pad_const);
& & }
& & else {& & & & & & & & & & & && switch ($str_pad_const) {
& & & & & & case STR_PAD_LEFT:
& & & & & & & & $str = substr($str, (strlen($str) - $len), $len);
& & & & & & & &
& & & & & & case STR_PAD_BOTH:
& & & & & & & & $shorten = (int) ((strlen($str) - $len) / 2);
& & & & & & & & $str = substr($str, $shorten, $len);
& & & & & & & &
& & & & & & default:
& & & & & & & & $str = substr($str, 0, $len);
& & & & & & & &
& & & & }
& & }
& & return ($len - $origLen);
}
?&
I wrote these 3 functions that live in a library i include in every programme. I find them useful, and the syntax is easy.&?php$str = "test";function str_pad_right ( $string , $padchar , $int ) {& & $i = strlen ( $string ) + $int;& & $str = str_pad ( $string , $i , $padchar , STR_PAD_RIGHT );& & return $str;}& & function str_pad_left ( $string , $padchar , $int ) {& & $i = strlen ( $string ) + $int;& & $str = str_pad ( $string , $i , $padchar , STR_PAD_LEFT );& & return $str;}& & function str_pad_both ( $string , $padchar , $int ) {& & $i = strlen ( $string ) + ( $int * 2 );& & $str = str_pad ( $string , $i , $padchar , STR_PAD_BOTH );& & return $str;}echo str_pad_left ( $str , "-" , 3 ); echo str_pad_right ( $str , "-" , 3 ); echo str_pad_both ( $str , "-" , 3 ); ?&Hope this can help someone!
&?php& & function str_pad_html($strInput = "", $intPadLength, $strPadString = "&", $intPadType = STR_PAD_RIGHT) {& & & & if (strlen(trim(strip_tags($strInput))) & intval($intPadLength)) {& & & & & & & & & & & & switch ($intPadType) {& & & & & & & && case 0:& & & & & & & & & & $offsetLeft = intval($intPadLength - strlen(trim(strip_tags($strInput))));& & & & & & & & & & $offsetRight = 0;& & & & & & & & & && & & & & & & & & & & & & & & & & & case 1:& & & & & & & & & & $offsetLeft = 0;& & & & & & & & & & $offsetRight = intval($intPadLength - strlen(trim(strip_tags($strInput))));& & & & & & & & & && & & & & & & & & & & & & & & & & & case 2:& & & & & & & & & & $offsetLeft = intval(($intPadLength - strlen(trim(strip_tags($strInput)))) / 2);& & & & & & & & & & $offsetRight = round(($intPadLength - strlen(trim(strip_tags($strInput)))) / 2, 0);& & & & & & & & & && & & & & & & & & & & & & & & & & & default:& & & & & & & & & & $offsetLeft = 0;& & & & & & & & & & $offsetRight = intval($intPadLength - strlen(trim(strip_tags($strInput))));& & & & & & & & & && & & & & & }& & & & & & & & & & & & $strPadded = str_repeat($strPadString, $offsetLeft) . $strInput . str_repeat($strPadString, $offsetRight);& & & & & & unset($strInput, $offsetLeft, $offsetRight);& & & & & & & & & & & & return $strPadded;& & & & }& & & & & & & & else {& & & & & & return $strInput;& & & & }& & }?&
Here is a simple function to convert numbers into strings like this:0 =& 00001 =& 000120 =& 0020432 =& 0432&?phpfunction number_pad($number,$n) {return str_pad((int) $number,$n,"0",STR_PAD_LEFT);}?&$n indicates how many characters you want.
For simple padding, you can use sprintf, which is faster:see
Example #5 "Specifying padding character"
When provided with a string of characters as the pad value, str_pad uses all the characters as fill, and can leave partial strings. (eg. If the pad value is 'ABC' and it needs 5 characters to pad with, it outputs 'ABCAB'.) This is a problem when you want to pad with non-breaking spaces, the code for which is 6 characters long. This can be resolved by first padding the string with a single character that won't be found in the strings such as * then doing a str_replace of * with &.
You can use trim functions for clearpad string:ltrim("0001230", "0") -& 1230rtrim("0123000", "0") -& 0123trim("0012300")& && -& 123MD5_百度百科
清除历史记录关闭
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
Message Digest Algorithm MD5(中文名为第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)。MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译、),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、和。MD5算法具有以下特点:1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。2、容易计算:从原数据计算出MD5值很容易。3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。MD5的作用是让大容量信息在用软件签署私人前被&&成一种保密的格式(就是把一个任意长度的字节串变换成一定长的数字串)。除了MD5以外,其中比较有名的还有、以及Haval等。
MD5发展历史
Rivest在1989年开发出MD2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的检验和追加到信息末尾,并且根据这个新产生的信息计算出散列值。后来,Rogier和Chauvaud发现如果忽略了检验将和MD2产生冲突。MD2算法后结果是唯一的(即不同信息加密后的结果不同)。
强算法的安全性,Rivest在1990年又开发出MD4算法。MD4算法同样需要填补信息以确保信息的比特位长度减去448后能被512整除(信息比特位长度mod 512 = 448)。然后,一个以64位表示的信息的最初长度被添加进来。信息被处理成512位damg?rd/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。Den boer和Bosselaers以及其他人很快的发现了攻击MD4版本中第一步和第三步的漏洞。Dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到MD4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)。毫无疑问,MD4就此被淘汰掉了。
尽管MD4算法在安全上有个这么大的漏洞,但它对在其后才被开发出来的好几种信息安全加密算法的出现却有着不可忽视的引导作用。
1991年,Rivest开发出技术上更为趋近成熟的。它在MD4的基础上增加了"安全-带子"(safety-belts)的概念。虽然MD5比MD4复杂度大一些,但却更为安全。这个算法很明显的由四个和MD4设计有少许不同的步骤组成。在中,信息-摘要的大小和填充的必要条件与MD4完全相同。Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。
MD5MD5应用
MD5一致性验证
典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。比如,在下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如:
MD5 (tanajiya.tar.gz) = 38b8c2c1093dd0fec383a9d9ac940515
这就是tanajiya.tar.gz文件的数字签名。MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。为了让读者朋友对MD5的应用有个直观的认识,笔者以一个比方和一个实例来简要描述一下其工作过程:
大家都知道,地球上任何人都有自己独一无二的,这常常成为司法机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的
“”,如果任何人对文件做了任何改动,其也就是对应的“数字指纹”都会发生变化。
我们常常在某些软件下载站点的某软件信息中看到其MD5值,它的作用就在于我们可以在下载该软件后,对下载回来的文件用专门的软件(如Windows MD5 Check等)做一次,以确保我们获得的文件与该站点提供的文件为同一文件。
具体来说文件的MD5值就像是这个文件的“”。每个文件的MD5值是不同的,如果任何人对文件做了任何改动,其也就是对应的“数字指纹”就会发生变化。比如下载服务器针对一个文件预先提供一个MD5值,用户下载完该文件后,用我这个算法重新计算下载文件的MD5值,通过比较这两个值是否相同,就能判断下载的文件是否出错,或者说下载的文件是否被篡改了。
利用MD5算法来进行文件校验的方案被大量应用到软件下载站、论坛数据库、系统文件安全等方面。
MD5数字签名
MD5的典型应用是对一段Message(字节串)产生fingerprint(),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。
MD5安全访问认证
MD5还广泛用于操作系统的登陆认证上,如Unix、各类登录密码、等诸多方面。如在Unix系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。MD5将任意长度的“字节串”映射为一个128bit的大整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,比较好的办法是:你可以用这个系统中的md5()函数重新设一个密码,如admin,把生成的一串密码的Hash值覆盖原来的Hash值就行了。
正是因为这个原因,现在被黑客使用最多的一种破译密码的方法就是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用MD5程序计算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索。我们假设密码的最大长度为8位字节(8 Bytes),同时密码只能是字母和数字,共26+26+10=62个字节,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是一个很天文的数字了,存储这个字典就需要TB级的,而且这种方法还有一个前提,就是能获得目标账户的密码MD5值的情况下才可以。这种加密技术被广泛的应用于Unix系统中,这也是为什么Unix系统比一般操作系统更为坚固一个重要原因。
MD5算法原理
对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
总体流程如下图所示,
表示第i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。
MD5算法的整体流程图
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448,并且填充必须进行,即使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448,N为一个非负整数,N可以是零。
填充的方法如下:
1) 在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。
2) 在这个结果后面附加一个以64位二进制表示的填充前信息长度(单位为Bit),如果二
进制表示的填充前信息长度超过64位,则取低64位。
经过这两步的处理,信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。
2. 初始化变量
初始的128位值为初试链接变量,这些参数用于第一轮的运算,以大端来表示,他们分别为: A=0x,B=0x89ABCDEF,C=0xFEDCBA98,D=0x。
(每一个变量给出的数值是高字节存于内存低地址,低字节存于内存高地址,即大端字节序。在程序中变量A、B、C、D的值分别为0xxEFCDAB89,0x98BADCFE,0x)
3. 处理分组数据
每一分组的算法流程如下:
第一分组需要将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第二分组开始的变量为上一分组的运算结果,即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) )
(&是与(And),|是或(Or),~是非(Not),^是异或(Xor))
这四个函数的说明:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
F是一个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。
假设Mj表示消息的第j个子分组(从0到15),常数ti是*abs( sin(i) )的整数部分,i 取值从1到64,单位是弧度。(=232)
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) && s)
HH(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + H(b,c,d) + Mj + ti) && s)
II(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + I(b,c,d) + Mj + ti) && s)
注意:“&&”表示循环左移位,不是左移位。
这四轮(共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 ,0x )
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 ,0x )
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 ,0x )
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 )
II(a ,b ,c ,d ,M0 ,6 ,0xf4292244 )
II(d ,a ,b ,c ,M7 ,10 ,0x432aff97 )
II(c ,d ,a ,b ,M14 ,15 ,0xab9423a7 )
II(b ,c ,d ,a ,M5 ,21 ,0xfc93a039 )
II(a ,b ,c ,d ,M12 ,6 ,0x655b59c3 )
II(d ,a ,b ,c ,M3 ,10 ,0x8f0ccc92 )
II(c ,d ,a ,b ,M10 ,15 ,0xffeff47d )
II(b ,c ,d ,a ,M1 ,21 ,0x85845dd1 )
II(a ,b ,c ,d ,M8 ,6 ,0x6fa87e4f )
II(d ,a ,b ,c ,M15 ,10 ,0xfe2ce6e0 )
II(c ,d ,a ,b ,M6 ,15 ,0xa3014314 )
II(b ,c ,d ,a ,M13 ,21 ,0x4e0811a1 )
II(a ,b ,c ,d ,M4 ,6 ,0xf7537e82 )
II(d ,a ,b ,c ,M11 ,10 ,0xbd3af235 )
II(c ,d ,a ,b ,M2 ,15 ,0x2ad7d2bb )
II(b ,c ,d ,a ,M9 ,21 ,0xeb86d391 )
所有这些完成之后,将a、b、c、d分别在原来基础上再加上A、B、C、D。
即a = a + A,b = b + B,c = c + C,d = d + D
然后用下一分组数据继续运行以上算法。
最后的输出是a、b、c和d的级联。
当你按照我上面所说的方法实现MD5算法以后,你可以用以下几个信息对你做出来的程序作一个简单的测试,看看程序有没有错误。
MD5 (&&) = d41d8cd98f00b204e9800998ecf8427e
MD5 (&a&) = 0cc175b9c0f1b6a831c399e
MD5 (&abc&) = cd24fb0de17f72
MD5 (&message digest&) = f96b697d7cbf31aaf161d0
MD5 (&abcdefghijklmnopqrstuvwxyz&) = c3fcd3ddfb496cca67e13b
MD5 (&ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&) =
f29939a25efabaef3b87e2cbfe641315
MD5 (&8a683566bccd8b0cf35fd97&) =cf2cb5c89c5e5eeebef4a76becddfcfd
MD5MD5加密字符串实例
现以字符串“jklmn”为例。
该字符串在内存中表示为:6A 6B 6C 6D 6E(从左到右为低地址到高地址,后同),信息长度为40 bits, 即0x28。
对其填充,填充至448位,即56字节。结果为:
6A 6B 6C 6D 6E 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
剩下64位,即8字节填充填充前信息位长,按小端字节序填充剩下的8字节,结果为。
6A 6B 6C 6D 6E 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00 00 00 00
(64字节,512 bits)
初始化A、B、C、D四个变量。
将这64字节填充后数据分成16个小组(程序中对应为16个数组),即:
M0:6A 6B 6C 6D (这是内存中的顺序,按照小端字节序原则,对应数组M(0)的值为0x6D6C6B6A,下同)
M1:6E 80 00 00
M2:00 00 00 00
M14:28 00 00 00
M15:00 00 00 00
经过“3. 分组数据处理”后,a、b、c、d值分别为0xDx837E726CA、0x1BB6E5FE
在内存中为a:60 3F 52 D8
b:44 01 7E 83
c:CA 26 77 51
d:FE E5 B6 1B
a、b、c、d按内存顺序输出即为最终结果:603F52DCA267751FEE5B61B。这就是字符串“jklmn”的MD5值。
MD5C++实现
#include&iostream&
#include&string&
using&namespace&
#define&shift(x,&n)&(((x)&&&&(n))&|&((x)&&&&(32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
#define&F(x,&y,&z)&(((x)&&&(y))&|&((~x)&&&(z)))&&&&
#define&G(x,&y,&z)&(((x)&&&(z))&|&((y)&&&(~z)))
#define&H(x,&y,&z)&((x)&^&(y)&^&(z))
#define&I(x,&y,&z)&((y)&^&((x)&|&(~z)))
#define&A&0x
#define&B&0xefcdab89
#define&C&0x98badcfe
#define&D&0x
//strBaye的长度
unsigned&int&
//A,B,C,D的临时变量
unsigned&int&
unsigned&int&
unsigned&int&
unsigned&int&
//常量ti&unsigned&int(abs(sin(i+1))*(2pow32))
const&unsigned&int&k[]={
&&&&&&&&0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
&&&&&&&&0xf57c0faf,0xxaxfdx,
&&&&&&&&0x8b44f7af,0xffff5bb1,0x895cd7be,0x6bxfd987193,
&&&&&&&&0xax49be0b340,0x265e5a51,
&&&&&&&&0xe9b6c7aa,0xd62f105d,0xxd8a1e681,0xe7d3fbc8,
&&&&&&&&0x21e1cde6,0xcxf4d50d87,0x455a14ed,0xa9e3e905,
&&&&&&&&0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa1f681,
&&&&&&&&0x6d9d6122,0xfdebeea44,0x4bdecfa9,0xf6bb4b60,
&&&&&&&&0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef81d05,
&&&&&&&&0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac92244,
&&&&&&&&0x432aff97,0xabxfc93a039,0x655b59c3,0x8f0ccc92,
&&&&&&&&0xffeff47d,0x8x6fa87e4f,0xfe2ce6e0,0xa3014314,
&&&&&&&&0x4exfxbd3af235,0x2ad7d2bb,0xeb86d391};
//向左位移数
const&unsigned&int&s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
&&&&&&&&12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
&&&&&&&&4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
&&&&&&&&15,21,6,10,15,21,6,10,15,21,6,10,15,21};
const&char&str16[]=&abcdef&;
void&mainLoop(unsigned&int&M[])
&&&&unsigned&int&f,g;
&&&&unsigned&int&a=
&&&&unsigned&int&b=
&&&&unsigned&int&c=
&&&&unsigned&int&d=
&&&&for&(unsigned&int&i&=&0;&i&&&64;&i++)
&&&&&&&&if(i&16){
&&&&&&&&&&&&f=F(b,c,d);
&&&&&&&&&&&&g=i;
&&&&&&&&}else&if&(i&32)
&&&&&&&&&&&&f=G(b,c,d);
&&&&&&&&&&&&g=(5*i+1)%16;
&&&&&&&&}else&if(i&48){
&&&&&&&&&&&&f=H(b,c,d);
&&&&&&&&&&&&g=(3*i+5)%16;
&&&&&&&&}else{
&&&&&&&&&&&&f=I(b,c,d);
&&&&&&&&&&&&g=(7*i)%16;
&&&&&&&&unsigned&int&tmp=d;
&&&&&&&&d=c;
&&&&&&&&c=b;
&&&&&&&&b=b+shift((a+f+k[i]+M[g]),s[i]);
&&&&&&&&a=
&&&&atemp=a+
&&&&btemp=b+
&&&&ctemp=c+
&&&&dtemp=d+
*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
*填充方式为先加一个1,其它位补零
*最后加上64位的原来长度
unsigned&int*&add(string&str)
&&&&unsigned&int&num=((str.length()+8)/64)+1;//以512位,64个字节为一组
&&&&unsigned&int&*strByte=new&unsigned&int[num*16];&&&&//64/4=16,所以有16个整数
&&&&strlength=num*16;
&&&&for&(unsigned&int&i&=&0;&i&&&num*16;&i++)
&&&&&&&&strByte[i]=0;
&&&&for&(unsigned&int&i=0;&i&&str.length();&i++)
&&&&&&&&strByte[i&&2]|=(str[i])&&((i%4)*8);//一个整数存储四个字节,i&&2表示i/4&一个unsigned&int对应4个字节,保存4个字符信息
&&&&strByte[str.length()&&2]|=0x80&&(((str.length()%4))*8);//尾部添加1&一个unsigned&int保存4个字符信息,所以用128左移
&&&&*添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
&&&&strByte[num*16-2]=str.length()*8;
&&&&return&strB
string&changeHex(int&a)
&&&&int&b;
&&&&string&str1;
&&&&string&str=&&;
&&&&for(int&i=0;i&4;i++)
&&&&&&&&str1=&&;
&&&&&&&&b=((a&&i*8)%(1&&8))&0&&&//逆序处理每个字节
&&&&&&&&for&(int&j&=&0;&j&&&2;&j++)
&&&&&&&&&&&&str1.insert(0,1,str16[b%16]);
&&&&&&&&&&&&b=b/16;
&&&&&&&&str+=str1;
&&&&return&
string&getMD5(string&source)
&&&&atemp=A;&&&&//初始化
&&&&btemp=B;
&&&&ctemp=C;
&&&&dtemp=D;
&&&&unsigned&int&*strByte=add(source);
&&&&for(unsigned&int&i=0;i&strlength/16;i++)
&&&&&&&&unsigned&int&num[16];
&&&&&&&&for(unsigned&int&j=0;j&16;j++)
&&&&&&&&&&&&num[j]=strByte[i*16+j];
&&&&&&&&mainLoop(num);
&&&&return&changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
unsigned&int&main()
&&&&string&
//&&&&cin&&
&&&&string&s=getMD5(&abc&);
&&&&cout&&s;
&&&&return&0;
MD5JAVA实现
public&class&MD5{
&&&&*四个链接变量
&&&&private&final&int&A=0x;
&&&&private&final&int&B=0xefcdab89;
&&&&private&final&int&C=0x98
&&&&private&final&int&D=0x;
&&&&*ABCD的临时变量
&&&&private&int&Atemp,Btemp,Ctemp,D
&&&&*常量ti
&&&&*公式:floor(abs(sin(i+1))×(2pow32)
&&&&private&final&int&K[]={
&&&&&&&&0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
&&&&&&&&0xf57c0faf,0xxaxfdx,
&&&&&&&&0x8b44f7af,0xffff5bb1,0x895cd7be,0x6bxfd987193,
&&&&&&&&0xax49be0b340,0x265e5a51,
&&&&&&&&0xe9b6c7aa,0xd62f105d,0xxd8a1e681,0xe7d3fbc8,
&&&&&&&&0x21e1cde6,0xcxf4d50d87,0x455a14ed,0xa9e3e905,
&&&&&&&&0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa1f681,
&&&&&&&&0x6d9d6122,0xfdebeea44,0x4bdecfa9,0xf6bb4b60,
&&&&&&&&0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef81d05,
&&&&&&&&0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac92244,
&&&&&&&&0x432aff97,0xabxfc93a039,0x655b59c3,0x8f0ccc92,
&&&&&&&&0xffeff47d,0x8x6fa87e4f,0xfe2ce6e0,0xa3014314,
&&&&&&&&0x4exfxbd3af235,0x2ad7d2bb,0xeb86d391};
&&&&*向左位移数,计算方法未知
&&&&private&final&int&s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
&&&&&&&&12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
&&&&&&&&4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
&&&&&&&&15,21,6,10,15,21,6,10,15,21,6,10,15,21};
&&&&*初始化函数
&&&&private&void&init(){
&&&&&&&&Atemp=A;
&&&&&&&&Btemp=B;
&&&&&&&&Ctemp=C;
&&&&&&&&Dtemp=D;
&&&&*移动一定位数
&&&&private&&&&int&&&&shift(int&a,int&s){
&&&&&&&&return(a&&s)|(a&&&(32-s));//右移的时候,高位一定要补零,而不是补充符号位
&&&&*主循环
&&&&private&void&MainLoop(int&M[]){
&&&&&&&&int&F,g;
&&&&&&&&int&a=A
&&&&&&&&int&b=B
&&&&&&&&int&c=C
&&&&&&&&int&d=D
&&&&&&&&for(int&i&=&0;&i&&&64;&i&++){
&&&&&&&&&&&&if(i&16){
&&&&&&&&&&&&&&&&F=(b&c)|((~b)&d);
&&&&&&&&&&&&&&&&g=i;
&&&&&&&&&&&&}else&if(i&32){
&&&&&&&&&&&&&&&&F=(d&b)|((~d)&c);
&&&&&&&&&&&&&&&&g=(5*i+1)%16;
&&&&&&&&&&&&}else&if(i&48){
&&&&&&&&&&&&&&&&F=b^c^d;
&&&&&&&&&&&&&&&&g=(3*i+5)%16;
&&&&&&&&&&&&}else{
&&&&&&&&&&&&&&&&F=c^(b|(~d));
&&&&&&&&&&&&&&&&g=(7*i)%16;
&&&&&&&&&&&&}
&&&&&&&&&&&&int&tmp=d;
&&&&&&&&&&&&d=c;
&&&&&&&&&&&&c=b;
&&&&&&&&&&&&b=b+shift(a+F+K[i]+M[g],s[i]);
&&&&&&&&&&&&a=
&&&&&&&&Atemp=a+A
&&&&&&&&Btemp=b+B
&&&&&&&&Ctemp=c+C
&&&&&&&&Dtemp=d+D
&&&&*填充函数
&&&&*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
&&&&*填充方式为先加一个0,其它位补零
&&&&*最后加上64位的原来长度
&&&&private&int[]&add(String&str){
&&&&&&&&int&num=((str.length()+8)/64)+1;//以512位,64个字节为一组
&&&&&&&&int&strByte[]=new&int[num*16];//64/4=16,所以有16个整数
&&&&&&&&for(int&i=0;i&num*16;i++){//全部初始化0
&&&&&&&&&&&&strByte[i]=0;
&&&&&&&&int&&&&i;
&&&&&&&&for(i=0;i&str.length();i++){
&&&&&&&&&&&&strByte[i&&2]|=str.charAt(i)&&((i%4)*8);//一个整数存储四个字节,小端序
&&&&&&&&strByte[i&&2]|=0x80&&((i%4)*8);//尾部添加1
&&&&&&&&/*
&&&&&&&&*添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
&&&&&&&&*/
&&&&&&&&strByte[num*16-2]=str.length()*8;
&&&&&&&&&&&&return&strB
&&&&*调用函数
&&&&public&String&getMD5(String&source){
&&&&&&&&init();
&&&&&&&&int&strByte[]=add(source);
&&&&&&&&for(int&i=0;i&strByte.length/16;i++){
&&&&&&&&int&num[]=new&int[16];
&&&&&&&&for(int&j=0;j&16;j++){
&&&&&&&&&&&&num[j]=strByte[i*16+j];
&&&&&&&&MainLoop(num);
&&&&&&&&return&changeHex(Atemp)+changeHex(Btemp)+changeHex(Ctemp)+changeHex(Dtemp);
&&&&*整数变成16进制字符串
&&&&private&String&changeHex(int&a){
&&&&&&&&String&str=&&;
&&&&&&&&for(int&i=0;i&4;i++){
&&&&&&&&&&&&str+=String.format(&%2s&,&Integer.toHexString(((a&&i*8)%(1&&8))&0xff)).replace('&',&'0');
&&&&&&&&return&
&&&&private&static&MD5&
&&&&public&static&MD5&getInstance(){
&&&&&&&&if(instance==null){
&&&&&&&&&&&&instance=new&MD5();
&&&&&&&&return&
&&&&private&MD5(){};
&&&&public&static&void&main(String[]&args){
&&&&&&&&String&str=MD5.getInstance().getMD5(&&);
&&&&&&&&System.out.println(str);
MD5VB2010实现
Imports&System
Imports&System.Security.Cryptography
Imports&System.Text
Module&Example
&&&&'哈希输入字符串并返回一个&32&字符的十六进制字符串哈希。
&&&&Function&GetMd5Hash(ByVal&input&As&String)&As&String
&&&&&&&&'创建新的一个&MD5CryptoServiceProvider&对象的实例。
&&&&&&&&Dim&md5Hasher&As&New&MD5CryptoServiceProvider()
&&&&&&&&'输入的字符串转换为字节数组,并计算哈希。
&&&&&&&&Dim&data&As&Byte()&=&md5Hasher.ComputeHash(Encoding.Default.GetBytes(input))
&&&&&&&&'创建一个新的&StringBuilder&收集的字节,并创建一个字符串。
&&&&&&&&Dim&sBuilder&As&New&StringBuilder()
&&&&&&&&'通过每个字节的哈希数据和格式为十六进制字符串的每一个循环。
&&&&&&&&For&i&As&Integer&=&0&To&data.Length&-&1
&&&&&&&&&&&&sBuilder.Append(data(i).ToString(&x2&))
&&&&&&&&Next
&&&&&&&&'返回十六进制字符串。
&&&&&&&&Return&sBuilder.ToString()
&&&&End&Function
&&&&'验证对一个字符串的哈希值。
&&&&Function&VerifyMd5Hash(ByVal&input&As&String,&ByVal&hash&As&String)&As&Boolean
&&&&&&&&'哈希的输入。
&&&&&&&&Dim&hashOfInput&As&String&=&GetMd5Hash(input)
&&&&&&&&'创建&StringComparer&的哈希进行比较。
&&&&&&&&Dim&comparer&As&StringComparer&=&StringComparer.OrdinalIgnoreCase
&&&&&&&&Return&comparer.Compare(hashOfInput,&hash)&=&0
&&&&End&Function
&&&&Sub&Main()
&&&&&&&&Dim&source&As&String&=&&Hello&World!&
&&&&&&&&Dim&hash&As&String&=&GetMd5Hash(source)
&&&&&&&&Console.WriteLine($&进行MD5加密的字符串为:{source},加密的结果是:{hash}。&)
&&&&&&&&Console.WriteLine(&正在验证哈希……&)
&&&&&&&&If&VerifyMd5Hash(source,&hash)&Then
&&&&&&&&&&&&Console.WriteLine(&哈希值是
相同的。&)
&&&&&&&&&&&&Console.WriteLine(&哈希值是不相同的。&)
&&&&EndSub
'此代码示例产生下面的输出:
'进行MD5加密的字符串为:Hello&World!,加密的结果是:ed365e841e92bfc50d8c。
'正在验证哈希……
'哈希值是相同的。
MD5JavaScript实现
function&md5(string)&{
function&md5_RotateLeft(lValue,&iShiftBits)&{
return&(lValue&&&&iShiftBits)&|&(lValue&&&&&(32&-&iShiftBits));
function&md5_AddUnsigned(lX,&lY)&{
var&lX4,&lY4,&lX8,&lY8,&lR
lX8&=&(lX&&&0x);
lY8&=&(lY&&&0x);
lX4&=&(lX&&&0x);
lY4&=&(lY&&&0x);
lResult&=&(lX&&&0x3FFFFFFF)&+&(lY&&&0x3FFFFFFF);
if&(lX4&&&lY4)&{
return&(lResult&^&0x&^&lX8&^&lY8);
if&(lX4&|&lY4)&{
if&(lResult&&&0x)&{
return&(lResult&^&0xC0000000&^&lX8&^&lY8);
return&(lResult&^&0x&^&lX8&^&lY8);
return&(lResult&^&lX8&^&lY8);
function&md5_F(x,&y,&z)&{
return&(x&&&y)&|&((~x)&&&z);
function&md5_G(x,&y,&z)&{
return&(x&&&z)&|&(y&&&(~z));
function&md5_H(x,&y,&z)&{
return&(x&^&y&^&z);
function&md5_I(x,&y,&z)&{
return&(y&^&(x&|&(~z)));
function&md5_FF(a,&b,&c,&d,&x,&s,&ac)&{
a&=&md5_AddUnsigned(a,&md5_AddUnsigned(md5_AddUnsigned(md5_F(b,&c,&d),&x),&ac));
return&md5_AddUnsigned(md5_RotateLeft(a,&s),&b);
function&md5_GG(a,&b,&c,&d,&x,&s,&ac)&{
a&=&md5_AddUnsigned(a,&md5_AddUnsigned(md5_AddUnsigned(md5_G(b,&c,&d),&x),&ac));
return&md5_AddUnsigned(md5_RotateLeft(a,&s),&b);
function&md5_HH(a,&b,&c,&d,&x,&s,&ac)&{
a&=&md5_AddUnsigned(a,&md5_AddUnsigned(md5_AddUnsigned(md5_H(b,&c,&d),&x),&ac));
return&md5_AddUnsigned(md5_RotateLeft(a,&s),&b);
function&md5_II(a,&b,&c,&d,&x,&s,&ac)&{
a&=&md5_AddUnsigned(a,&md5_AddUnsigned(md5_AddUnsigned(md5_I(b,&c,&d),&x),&ac));
return&md5_AddUnsigned(md5_RotateLeft(a,&s),&b);
function&md5_ConvertToWordArray(string)&{
var&lWordC
var&lMessageLength&=&string.
var&lNumberOfWords_temp1&=&lMessageLength&+&8;
var&lNumberOfWords_temp2&=&(lNumberOfWords_temp1&-&(lNumberOfWords_temp1&%&64))&/&64;
var&lNumberOfWords&=&(lNumberOfWords_temp2&+&1)&*&16;
var&lWordArray&=&Array(lNumberOfWords&-&1);
var&lBytePosition&=&0;
var&lByteCount&=&0;
while&(lByteCount&&&lMessageLength)&{
lWordCount&=&(lByteCount&-&(lByteCount&%&4))&/&4;
lBytePosition&=&(lByteCount&%&4)&*&8;
lWordArray[lWordCount]&=&(lWordArray[lWordCount]&|&(string.charCodeAt(lByteCount)&&&&lBytePosition));
lByteCount++;
lWordCount&=&(lByteCount&-&(lByteCount&%&4))&/&4;
lBytePosition&=&(lByteCount&%&4)&*&8;
lWordArray[lWordCount]&=&lWordArray[lWordCount]&|&(0x80&&&&lBytePosition);
lWordArray[lNumberOfWords&-&2]&=&lMessageLength&&&&3;
lWordArray[lNumberOfWords&-&1]&=&lMessageLength&&&&&29;
return&lWordA
function&md5_WordToHex(lValue)&{
var&WordToHexValue&=&&&,
WordToHexValue_temp&=&&&,
for&(lCount&=&0;&lCount&&=&3;&lCount++)&{
lByte&=&(lValue&&&&&(lCount&*&8))&&&255;
WordToHexValue_temp&=&&0&&+&lByte.toString(16);
WordToHexValue&=&WordToHexValue&+&WordToHexValue_temp.substr(WordToHexValue_temp.length&-&2,&2);
return&WordToHexV
function&md5_Utf8Encode(string)&{
string&=&string.replace(/\r\n/g,&&\n&);
var&utftext&=&&&;
for&(var&n&=&0;&n&&&string.&n++)&{
var&c&=&string.charCodeAt(n);
if&(c&&&128)&{
utftext&+=&String.fromCharCode(c);
}&else&if&((c&&&127)&&&&(c&&&2048))&{
utftext&+=&String.fromCharCode((c&&&&6)&|&192);
utftext&+=&String.fromCharCode((c&&&63)&|&128);
utftext&+=&String.fromCharCode((c&&&&12)&|&224);
utftext&+=&String.fromCharCode(((c&&&&6)&&&63)&|&128);
utftext&+=&String.fromCharCode((c&&&63)&|&128);
var&x&=&Array();
var&k,&AA,&BB,&CC,&DD,&a,&b,&c,&d;
var&S11&=&7,
var&S21&=&5,
var&S31&=&4,
var&S41&=&6,
string&=&md5_Utf8Encode(string);
x&=&md5_ConvertToWordArray(string);
b&=&0xEFCDAB89;
c&=&0x98BADCFE;
for&(k&=&0;&k&&&x.&k&+=&16)&{
a&=&md5_FF(a,&b,&c,&d,&x[k&+&0],&S11,&0xD76AA478);
d&=&md5_FF(d,&a,&b,&c,&x[k&+&1],&S12,&0xE8C7B756);
c&=&md5_FF(c,&d,&a,&b,&x[k&+&2],&S13,&0x242070DB);
b&=&md5_FF(b,&c,&d,&a,&x[k&+&3],&S14,&0xC1BDCEEE);
a&=&md5_FF(a,&b,&c,&d,&x[k&+&4],&S11,&0xF57C0FAF);
d&=&md5_FF(d,&a,&b,&c,&x[k&+&5],&S12,&0x4787C62A);
c&=&md5_FF(c,&d,&a,&b,&x[k&+&6],&S13,&0xA8304613);
b&=&md5_FF(b,&c,&d,&a,&x[k&+&7],&S14,&0xFD469501);
a&=&md5_FF(a,&b,&c,&d,&x[k&+&8],&S11,&0x);
d&=&md5_FF(d,&a,&b,&c,&x[k&+&9],&S12,&0x8B44F7AF);
c&=&md5_FF(c,&d,&a,&b,&x[k&+&10],&S13,&0xFFFF5BB1);
b&=&md5_FF(b,&c,&d,&a,&x[k&+&11],&S14,&0x895CD7BE);
a&=&md5_FF(a,&b,&c,&d,&x[k&+&12],&S11,&0x6B901122);
d&=&md5_FF(d,&a,&b,&c,&x[k&+&13],&S12,&0xFD987193);
c&=&md5_FF(c,&d,&a,&b,&x[k&+&14],&S13,&0xA679438E);
b&=&md5_FF(b,&c,&d,&a,&x[k&+&15],&S14,&0x49B40821);
a&=&md5_GG(a,&b,&c,&d,&x[k&+&1],&S21,&0xF61E2562);
d&=&md5_GG(d,&a,&b,&c,&x[k&+&6],&S22,&0xC040B340);
c&=&md5_GG(c,&d,&a,&b,&x[k&+&11],&S23,&0x265E5A51);
b&=&md5_GG(b,&c,&d,&a,&x[k&+&0],&S24,&0xE9B6C7AA);
a&=&md5_GG(a,&b,&c,&d,&x[k&+&5],&S21,&0xD62F105D);
d&=&md5_GG(d,&a,&b,&c,&x[k&+&10],&S22,&0x2441453);
c&=&md5_GG(c,&d,&a,&b,&x[k&+&15],&S23,&0xD8A1E681);
b&=&md5_GG(b,&c,&d,&a,&x[k&+&4],&S24,&0xE7D3FBC8);
a&=&md5_GG(a,&b,&c,&d,&x[k&+&9],&S21,&0x21E1CDE6);
d&=&md5_GG(d,&a,&b,&c,&x[k&+&14],&S22,&0xC33707D6);
c&=&md5_GG(c,&d,&a,&b,&x[k&+&3],&S23,&0xF4D50D87);
b&=&md5_GG(b,&c,&d,&a,&x[k&+&8],&S24,&0x455A14ED);
a&=&md5_GG(a,&b,&c,&d,&x[k&+&13],&S21,&0xA9E3E905);
d&=&md5_GG(d,&a,&b,&c,&x[k&+&2],&S22,&0xFCEFA3F8);
c&=&md5_GG(c,&d,&a,&b,&x[k&+&7],&S23,&0x676F02D9);
b&=&md5_GG(b,&c,&d,&a,&x[k&+&12],&S24,&0x8D2A4C8A);
a&=&md5_HH(a,&b,&c,&d,&x[k&+&5],&S31,&0xFFFA3942);
d&=&md5_HH(d,&a,&b,&c,&x[k&+&8],&S32,&0x);
c&=&md5_HH(c,&d,&a,&b,&x[k&+&11],&S33,&0x6D9D6122);
b&=&md5_HH(b,&c,&d,&a,&x[k&+&14],&S34,&0xFDE5380C);
a&=&md5_HH(a,&b,&c,&d,&x[k&+&1],&S31,&0xA4BEEA44);
d&=&md5_HH(d,&a,&b,&c,&x[k&+&4],&S32,&0x4BDECFA9);
c&=&md5_HH(c,&d,&a,&b,&x[k&+&7],&S33,&0xF6BB4B60);
b&=&md5_HH(b,&c,&d,&a,&x[k&+&10],&S34,&0xBEBFBC70);
a&=&md5_HH(a,&b,&c,&d,&x[k&+&13],&S31,&0x289B7EC6);
d&=&md5_HH(d,&a,&b,&c,&x[k&+&0],&S32,&0xEAA127FA);
c&=&md5_HH(c,&d,&a,&b,&x[k&+&3],&S33,&0xD4EF3085);
b&=&md5_HH(b,&c,&d,&a,&x[k&+&6],&S34,&0x4881D05);
a&=&md5_HH(a,&b,&c,&d,&x[k&+&9],&S31,&0xD9D4D039);
d&=&md5_HH(d,&a,&b,&c,&x[k&+&12],&S32,&0xE6DB99E5);
c&=&md5_HH(c,&d,&a,&b,&x[k&+&15],&S33,&0x1FA27CF8);
b&=&md5_HH(b,&c,&d,&a,&x[k&+&2],&S34,&0xC4AC5665);
a&=&md5_II(a,&b,&c,&d,&x[k&+&0],&S41,&0xF4292244);
d&=&md5_II(d,&a,&b,&c,&x[k&+&7],&S42,&0x432AFF97);
c&=&md5_II(c,&d,&a,&b,&x[k&+&14],&S43,&0xAB9423A7);
b&=&md5_II(b,&c,&d,&a,&x[k&+&5],&S44,&0xFC93A039);
a&=&md5_II(a,&b,&c,&d,&x[k&+&12],&S41,&0x655B59C3);
d&=&md5_II(d,&a,&b,&c,&x[k&+&3],&S42,&0x8F0CCC92);
c&=&md5_II(c,&d,&a,&b,&x[k&+&10],&S43,&0xFFEFF47D);
b&=&md5_II(b,&c,&d,&a,&x[k&+&1],&S44,&0x85845DD1);
a&=&md5_II(a,&b,&c,&d,&x[k&+&8],&S41,&0x6FA87E4F);
d&=&md5_II(d,&a,&b,&c,&x[k&+&15],&S42,&0xFE2CE6E0);
c&=&md5_II(c,&d,&a,&b,&x[k&+&6],&S43,&0xA3014314);
b&=&md5_II(b,&c,&d,&a,&x[k&+&13],&S44,&0x4E0811A1);
a&=&md5_II(a,&b,&c,&d,&x[k&+&4],&S41,&0xF7537E82);
d&=&md5_II(d,&a,&b,&c,&x[k&+&11],&S42,&0xBD3AF235);
c&=&md5_II(c,&d,&a,&b,&x[k&+&2],&S43,&0x2AD7D2BB);
b&=&md5_II(b,&c,&d,&a,&x[k&+&9],&S44,&0xEB86D391);
a&=&md5_AddUnsigned(a,&AA);
b&=&md5_AddUnsigned(b,&BB);
c&=&md5_AddUnsigned(c,&CC);
d&=&md5_AddUnsigned(d,&DD);
return&(md5_WordToHex(a)&+&md5_WordToHex(b)&+&md5_WordToHex(c)&+&md5_WordToHex(d)).toLowerCase();
MD5伪代码实现
//Note:Allvariablesareunsigned32bitsandwrapmodulo2^32whencalculatingvarint[64]r,k//rspecifiestheper-roundshiftamountsr[0..15]:={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22}r[16..31]:={5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20}r[32..47]:={4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23}r[48..63]:={6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21}//Usebinaryintegerpartofthesinesofintegersasconstants:forifrom0to63k[i]:=floor(abs(sin(i+1))×2^32)//Initializevariables:varinth0:=0xvarinth1:=0xEFCDAB89varinth2:=0x98BADCFEvarinth3:=0x//Pre-processing:append&1&bittomessageappend&0&bitsuntilmessagelengthinbits≡448(mod512)appendbitlengthofmessageas64-bitlittle-endianintegertomessage//Processthemessageinsuccessive512-bitchunks:foreach512-bitchunkofmessagebreakchunkintosixteen32-bitlittle-endianwordsw[i],0≤i≤15//Initializehashvalueforthischunk:varinta:=h0varintb:=h1varintc:=h2varintd:=h3//Mainloop:forifrom0to63if0≤i≤15thenf:=(bandc)or((notb)andd)g:=ielseif16≤i≤31f:=(dandb)or((notd)andc)g:=(5×i+1)mod16elseif32≤i≤47f:=bxorcxordg:=(3×i+5)mod16elseif48≤i≤63f:=cxor(bor(notd))g:=(7×i)mod16temp:=dd:=cc:=bb:=((a+f+k[i]+w[g])leftrotater[i])+ba:=temp//Addthischunk'shashtoresultsofar:h0:=h0+ah1:=h1+bh2:=h2+ch3:=h3+dvarintdigest:=h0appendh1appendh2appendh3//(expressedaslittle-endian)MD5加密工具
利用MD5的算法原理,可以使用各种计算机语言进行实现,形成各种各样的MD5加密校验工具。有很多的在线工具可以实现这一点,这些在线工具一般是采用语言实现,使用非常方便快捷。[2]
Van oorschot和Wiener曾经考虑过一个在散列中暴力搜寻冲突的函数(brute-force hash function),而且他们猜测一个被设计专门用来搜索MD5冲突的机器(这台机器在1994年的制造成本大约是一百万美元)可以平均每24天就找到一个冲突。但单从1991年到2001年这10年间,竟没有出现替代MD5算法的MD6或被叫做其他什么名字的新算法这一点,我们就可以看出这个瑕疵并没有太多的影响MD5的安全性。上面所有这些都不足以成为MD5的在实际应用中的问题。并且,由于MD5算法的使用不需要支付任何版权费用的,所以在一般的情况下(非绝密应用领域。但即便是应用在绝密领域内,MD5也不失为一种非常优秀的中间技术),MD5怎么都应该算得上是非常安全的了。
日的美国圣巴巴拉的国际会议(Crypto’2004)上,来自中国山东大学的教授做了破译MD5、HAVAL-128、 MD4和RIPEMD算法的报告,公布了MD系列算法的破解结果。宣告了固若金汤的世界通行密码标准MD5的堡垒轰然倒塌,引发了密码学界的轩然大波。(注意:并非是真正的破解,只是加速了杂凑冲撞)
令世界顶尖密码学家想象不到的是,破解MD5之后,2005年2月,王小云教授又破解了另一国际密码SHA-1。因为SHA-1在美国等国际社会有更加广泛的应用,密码被破的消息一出,在国际社会的反响可谓石破天惊。换句话说,王小云的研究成果表明了从理论上讲电子签名可以伪造,必须及时添加限制条件,或者重新选用更为安全的密码标准,以保证电子商务的安全。
MD5验证可执行文件不再可靠的消息
MD5破解工程权威网站是为了公开征集专门针对MD5的攻击而设立的,网站于日宣布:“人员发现了完整MD5算法的碰撞;Wang,Feng,Lai,Yu公布了MD5、MD4、HAVAL-128、RIPEMD-128几个 Hash函数的碰撞。这是近年来领域最具实质性的研究进展。使用他们的技术,在数个小时内就可以找到MD5碰撞。……由于这个里程碑式的发现,MD5CRK项目将在随后48小时内结束”。
在2004年8月之前,国际密码学界对这个名字并不熟悉。2004年8月,在美国圣芭芭拉召开的国际密码大会上,并没有被安排发言的王小云教授拿着自己的研究成果找到,没想到慧眼识珠的会议主席破例给了她15分钟时间来介绍自己的成果,而通常发言人只被允许有两三分钟的时间。王小云与助手展示了MD5、SHA-0及其他相关杂凑函数的杂凑冲撞。所谓杂凑冲撞指两个完全不同的讯息经杂凑函数计算得出完全相同的杂凑值。根据,以有长度限制的杂凑函数计算没有长度限制的讯息是必然会有冲撞情况出现的。可是,一直以来,电脑保安专家都认为要任意制造出冲撞需时太长,在实际情况上不可能发生,而王小云等的发现可能会打破这个必然性。就这样,王小云在国际会议上首次宣布了她及她的研究小组的研究成果——对、MD5、HAVAL-128和等四个著名密码算法的破译结果。
在公布到第三个成果的时候,会场上已经是掌声四起,报告不得不一度中断。报告结束后,所有与会专家对他们的突出工作报以长时间的掌声,有些学者甚至起立鼓掌以示他们的祝贺和敬佩。由于版本问题,作者在提交时使用的一组常数和先行标准不同,在发现这一问题之后,王小云教授立即改变了那个常数,在很短的时间内就完成了新的数据分析,这段有惊无险的小插曲更证明了他们论文的信服力,攻击方法的有效性,验证了研究工作的成功。
2005年8月,王小云、,以及姚期智妻子(即为Knuth起名的人)联手于国际密码讨论年会尾声部份提出SHA-1杂凑函数杂凑冲撞演算法的改良版。此改良版使破解SHA-1时间缩短。
日,教授于中国科学院第13次院士大会和第8次院士大会上以“国际通用Hash函数的破解”获颁信息技术科学奖。
2009年,冯登国、谢涛二人利用差分攻击,将MD5的碰撞算法复杂度从王小云的2^42进一步降低到2^21,极端情况下甚至可以降低至2^10。仅仅2^21的复杂度意味着即便是在2008年的计算机上,也只要几秒便可以找到一对碰撞。[1]
MD5("")= d41d8cd98f00b204e9800998ecf8427e[3]
PHP md5() 函数定义和用法
md5() 函数计算字符串的 MD5 散列。[4]
md5() 函数使用 RSA 数据安全,包括 MD5 报文摘要算法。
来自 RFC 1321 的解释 - MD5 报文摘要算法:MD5 报文摘要算法将任意长度的信息作为输入值,并将其换算成一个 128 位长度的"指纹信息"或"报文摘要"值来代表这个输入值,并以换算后的值作为结果。MD5 算法主要是为数字签名应用程序而设计的;在这个数字签名应用程序中,较大的文件将在加密(这里的加密过程是通过在一个密码系统下[如:RSA]的公开密钥下设置私有密钥而完成的)之前以一种安全的方式进行压缩。
如需计算文件的 MD5 散列,请使用 md5_file() 函数。
md5(string,raw)
参数描述string必需。规定要计算的字符串。raw可选。规定十六进制或二进制输出格式:
TRUE - 原始 16 字符二进制格式
FALSE - 默认。32 字符十六进制数
如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE。
PHP 版本:
更新日志:
在 PHP 5.0 中,raw 参数变成可选的。
输出 md5() 的结果:
&?php$str="Hello";echo"Thestring:".$str."&br&";echo"TRUE-Raw16characterbinaryformat:".md5($str,TRUE)."&br&";echo"FALSE-32characterhexnumber:".md5($str)."&br&";?&
.International Association for Cryptologic Research.2009年[引用日期]
.aTool在线工具[引用日期]
.维基[引用日期]
.w3cschool.[引用日期]
清除历史记录关闭}

我要回帖

更多关于 hello babyt ara 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信