探讨PHP自定义MD5加密函数的实现问题
作者:手机用户2502887185 | 来源:互联网 | 2024-12-15 18:00
本文分析了一个基于ASP代码改编的PHPMD5加密函数,指出其存在的问题,并提供了解决方案。通过对比ASP和PHP在处理相同数据时的不同表现,探讨了两种语言在实现MD5算法上的细微差别。
### 分析与讨论
#### 1. 代码来源及问题概述
观察代码可以发现,这段PHP MD5加密函数显然是从ASP代码转换而来。由于两种语言在处理整数和位操作上的差异,直接移植的代码在PHP环境下运行时出现了问题。主要表现为输出结果与预期不符。
#### 2. 代码分析
- **位移操作**:PHP和ASP在处理位移操作时存在差异,特别是对于32位以上的数值。PHP中,当数值超出32位时,默认会将其转换为浮点数,这可能导致计算结果的偏差。
- **整数处理**:PHP中默认整数为有符号类型,而ASP中某些情况下可能会将高位为1的值视为负数。这种差异在处理MD5算法中的某些特定步骤时尤为明显。
#### 3. 问题解决
- **修正位移操作**:确保所有位移操作都在32位范围内进行,避免数值溢出导致的错误。
- **整数类型转换**:在必要时使用`intval()`函数将浮点数强制转换为整数,以保证与ASP中类似的操作一致性。
#### 4. 代码示例
```php
function LShift($lValue, $iShiftBits) {
if ($iShiftBits == 0) return $lValue;
if ($iShiftBits == 31) {
if ($lValue & 1) { return 0x80000000; }
else { return 0; }
}
if ($iShiftBits <0 || $iShiftBits > 31) { return 0; }
return ($lValue <<$iShiftBits) | (($lValue & 0xFFFFFFFF) >> (32 - $iShiftBits));
}
function RShift($lValue, $iShiftBits) {
if ($iShiftBits == 0) return $lValue;
if ($iShiftBits == 31) {
if ($lValue & 0x80000000) { return 1; }
else { return 0; }
}
if ($iShiftBits <0 || $iShiftBits > 31) { return 0; }
return ($lValue >> $iShiftBits) | (($lValue & 0x7FFFFFFF) <<(32 - $iShiftBits));
}
// 其他函数如 RotateLeft, AddUnsigned, md5_F, md5_G, md5_H, md5_I, md5_FF, md5_GG, md5_HH, md5_II 等保持不变
function ConvertToWordArray($sMessage) {
$lWordArray = array();
$MODULUS_BITS = 512;
$CONGRUENT_BITS = 448;
$lMessageLength = strlen($sMessage);
$lNumberOfWords = (floor(($lMessageLength + floor(($MODULUS_BITS - $CONGRUENT_BITS) / 8)) / floor($MODULUS_BITS / 8)) + 1) * floor($MODULUS_BITS / 32);
$lBytePosition = 0;
$lByteCount = 0;
while (!($lByteCount >= $lMessageLength)) {
$lWordCount = floor($lByteCount / 4);
$lBytePosition = ($lByteCount % 4) * 8;
$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | LShift(ord(substr($sMessage, $lByteCount, 1)), $lBytePosition);
$lByteCount++;
}
$lWordCount = floor($lByteCount / 4);
$lBytePosition = ($lByteCount % 4) * 8;
$lWordArray[$lWordCount] = $lWordArray[$lWordCount] | LShift(0x80, $lBytePosition);
$lWordArray[$lNumberOfWords - 2] = LShift($lMessageLength, 3);
$lWordArray[$lNumberOfWords - 1] = RShift($lMessageLength, 29);
return $lWordArray;
}
function WordToHex($lValue) {
$tmpstr = '';
for ($lCount = 0; $lCount <= 3; $lCount++) {
$lByte = RShift($lValue, $lCount * 8) & 0xFF;
$tmpstr .= substr('0' . dechex($lByte), -2, 2);
}
return $tmpstr;
}
function php_MD5($sMessage) {
// 初始化全局变量
for ($i = 0; $i <= 30; $i++) {
$GLOBALS[$i] = intval(pow(2, $i));
}
$S11 = 7; $S12 = 12; $S13 = 17; $S14 = 22;
$S21 = 5; $S22 = 9; $S23 = 14; $S24 = 20;
$S31 = 4; $S32 = 11; $S33 = 16; $S34 = 23;
$S41 = 6; $S42 = 10; $S43 = 15; $S44 = 21;
$x = ConvertToWordArray($sMessage);
$a = 0x67452301; $b = 0xEFCDAB89; $c = 0x98BADCFE; $d = 0x10325476;
for ($k = 0; $k $AA = $a; $BB = $b; $CC = $c; $DD = $d;
// 执行MD5算法的各个步骤
md5_FF($a, $b, $c, $d, $x[$k + 0], $S11, 0xD76AA478);
md5_FF($d, $a, $b, $c, $x[$k + 1], $S12, 0xE8C7B756);
// ... (其他步骤)
$a = AddUnsigned($a, $AA);
$b = AddUnsigned($b, $BB);
$c = AddUnsigned($c, $CC);
$d = AddUnsigned($d, $DD);
}
return strtolower(WordToHex($a) . WordToHex($b) . WordToHex($c) . WordToHex($d));
}
$aaa = 'abcd';
echo php_MD5($aaa) . '
' . md5($aaa);
```
### 结论
通过对代码的详细分析和调整,我们可以使PHP自定义的MD5加密函数与ASP中的实现保持一致。尽管不同编程语言在处理相同算法时可能存在细微差异,但通过适当的调整,我们仍然可以实现跨平台的一致性。
推荐阅读
-
蜡笔小新 2024-12-14 15:17:26
-
本文详细记录了在DELL Inspiron 14R笔记本电脑上安装CentOS X64 6.4操作系统的过程,包括遇到的问题及解决方法。 ...
[详细]
蜡笔小新 2024-12-15 18:10:54
-
-
本文介绍了Spring Boot的基本概念及其在现代Java应用程序开发中的作用。Spring Boot旨在简化Spring应用的初始设置和开发过程,通过自动配置和约定优于配置的原则,帮助开发者快速构建基于Spring框架的应用。 ...
[详细]
蜡笔小新 2024-12-15 18:06:07
-
本文作为前文关于OAuth2.0和使用.NET实现OAuth身份验证的补充,详细阐述了OAuth与JWT及OpenID Connect之间的关系和差异,旨在提供更全面的理解。 ...
[详细]
蜡笔小新 2024-12-14 18:34:43
-
本文介绍了两种使用Java发送短信的方法:利用第三方平台的HTTP请求和通过硬件设备短信猫。重点讲解了如何通过Java代码配置和使用短信猫发送短信的过程,包括必要的编码转换、串口操作及短信发送的核心逻辑。 ...
[详细]
蜡笔小新 2024-12-14 18:08:31
-
本文探讨了使用Apache、Memcached-Session-Manager和Tomcat集群构建高性能Web应用过程中遇到的问题及解决方案。通过重新设计物理架构,解决了单虚拟机环境无法真实模拟分布式环境的问题,并详细记录了性能测试结果。 ...
[详细]
蜡笔小新 2024-12-14 10:07:53
-
本文探讨了如何在无向图中寻找一条从指定起点出发,确保不会连续两次访问同一条边的情况下,获得最大成本路径的方法。 ...
[详细]
蜡笔小新 2024-12-13 20:04:44
-
在使用 iOS 应用时,遇到网络请求错误是常见的问题。本文将探讨两种常见的错误代码 -1003 和 -1001,并提供详细的解释和解决方案。 ...
[详细]
蜡笔小新 2024-12-13 14:26:58
-
本文详细介绍了不同媒体容器支持的字幕格式,以及如何使用FFPlay和FFMPEG进行字幕和LRC歌词的播放与转换。涵盖的内容包括字幕显示方法、字体配置、字幕流选择等。 ...
[详细]
蜡笔小新 2024-12-13 13:13:40
-
本文探讨了亚马逊Go如何通过技术创新推动零售业的发展,以及面临的市场和隐私挑战。同时,介绍了亚马逊最新的‘刷手支付’技术及其潜在影响。 ...
[详细]
蜡笔小新 2024-12-13 11:39:37
-
本文详细介绍了Java SE的基础知识,包括Java的基本数据类型、运算符、程序控制结构、数组以及面向对象编程的核心概念。同时,文章还涵盖了JDK的概念及其在Java开发中的应用。 ...
[详细]
蜡笔小新 2024-12-13 09:45:37
-
随着毕业设计的结束,我终于有时间更新我的博客了。这次,我将分享如何在自己的服务器上搭建 Bitwarden,一个广受好评的开源密码管理工具。 ...
[详细]
蜡笔小新 2024-12-12 22:06:57
-
本文详细介绍了如何在Ubuntu系统上快速安装和配置Bitnami版本的GitLab,包括下载安装文件、执行安装过程以及设置邮件服务等步骤。 ...
[详细]
蜡笔小新 2024-12-12 19:02:32
-
本文深入探讨了如何利用Java语言结合Tesseract-OCR技术来实现图像中的数字识别功能,旨在为开发者提供详细的指导和实践案例。 ...
[详细]
蜡笔小新 2024-12-12 10:47:15
-
本文深入解析了PHP中输出缓冲(Output Buffering)的原理及其在Web开发中的应用,特别是如何通过输出缓冲技术有效管理HTTP头部信息,提高代码的灵活性与健壮性。 ...
[详细]
蜡笔小新 2024-12-12 10:37:27
-
手机用户2502887185
这个家伙很懒,什么也没留下!