当前位置: 首页 > 知识库问答 >
问题:

为什么这些PHP和Java密码生成器会产生不同的输出?[副本]

谭云瀚
2023-03-14

我正在为PHP中的脚本编写密码生成器,我希望它与我在Java中编写的类兼容,以便它们可以共享资源。

PHP代码:

public function PasswordGen($password, $rounds) { 
    for($i = 0; $i < $rounds; $i++) { 
        $password = substr(base64_encode(md5($password)), 0, 16); 
        echo $i . " " . $password . PHP_EOL; // debugging //
    }
    return $password;
}

Java代码:

public static String PasswordGen(String password, int rounds) {
    try { 
        for(int i = 0; i < rounds; i++) { 
            byte[] md5 = MessageDigest.getInstance("MD5").digest(password.getBytes("UTF-8"));
            String md5h = (new BigInteger(1, md5)).toString(16);
            password = Base64.getEncoder().encodeToString(md5h.getBytes()).substring(0, 16);
            System.out.println(Integer.toString(i) + " " + password); // debugging //
        }
    } catch(Exception ex) {
        ex.printStackTrace();
        return null;
    }
    return password;
}

PHP调试输出:

0 MWExZGM5MWM5MDcz  
1 NDVkZmMxNWVjNWZi  
2 ODY5YzVkODBhNTRh  
3 ZGE2OTNiOWMxOWM1  
4 OTcxMTY3MzgxMmRk  
5 NWNjNDI2N2IzMDlj  
6 NGVkYzY0YjVkMWUy  
7 MjdhMGU4NjhhNmU3  
8 OWY5OGE3ZGZiODZl  
9 Y2I1ZjBkNjRmMjkx  
10 YTk5NDA1MGI1OWY1  
11 YzRmYWE5ZTk0ZDdl  
12 NDBiZWZkNmQ5Yjhj  
13 MzQyNzcwNGRjMTYw  
14 N2U4ZmUxOGMyNWYx  
15 MjBjOTZhNGE4ZDQ1  
16 MjdmMzkwMzI0NDdj  
17 YjM4NDI0YWU0YzUw  
18 NDRiNjA1MWUwOGZi  
19 MGI1YmIyMDViMGYz  

Java调试输出:

0 MWExZGM5MWM5MDcz  
1 NDVkZmMxNWVjNWZi  
2 ODY5YzVkODBhNTRh  
3 ZGE2OTNiOWMxOWM1  
4 OTcxMTY3MzgxMmRk  
5 NWNjNDI2N2IzMDlj  
6 NGVkYzY0YjVkMWUy  
7 MjdhMGU4NjhhNmU3  
8 OWY5OGE3ZGZiODZl  
9 Y2I1ZjBkNjRmMjkx  
10 YTk5NDA1MGI1OWY1  
11 YzRmYWE5ZTk0ZDdl  
12 NDBiZWZkNmQ5Yjhj  
13 MzQyNzcwNGRjMTYw  
14 N2U4ZmUxOGMyNWYx  
15 MjBjOTZhNGE4ZDQ1  
16 MjdmMzkwMzI0NDdj  
17 YjM4NDI0YWU0YzUw  
18 NDRiNjA1MWUwOGZi  
19 YjViYjIwNWIwZjMy  

它一直按预期工作到第19个循环。为什么在那之后它会产生不同的输出?

共有1个答案

曹旭
2023-03-14

Java,使用toString(int base)方法将BigDecimal转换为十六进制字符串不会输出前导零。

您可以通过打印中间步骤的输出(将md5哈希代码转换为十六进制字符串)来发现这一点,在Java中,它给出了b5bb205b0f32a7bf2a80fc870cbd2b7,而在PHP中,它给出了0b5bb205b0f32a7bf2a80fc870cbd2b7。这只是一个前导零的差异,但在应用base64编码后,它们看起来非常不同。

获取前导零的一种更简单的方法是使用字符串。格式化方法。

替换此行:

String md5h = ( new BigInteger(1, md5) ).toString(16);

使用此行:

String md5h = String.format("%032x", new BigInteger(1, md5));

您将获得与php代码相同的输出。

 类似资料: