Java 到 PHP 代码差异

Java to PHP code difference

我得到了一段代码,其中描述了用于生成令牌的 "algorithm"。此代码是用 Java 编写的,并且可以正常工作。 给定的 Java 代码必须保持原样 ,但是,我的要求是在 PHP 应用程序中使用相同的 "algorithm",并且我'我很难检索到相同的结果。

Java代码:

public static void main(String[] args)
        throws
        UnsupportedEncodingException,
        NoSuchAlgorithmException {

    // Let's stick to a fixed date for this SO question
    //DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
    //dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    //String date = dateFormat.format(new Date());
    String date = "201603251605";
    String name = "some_dummy_data_one";
    String size = "some_dummy_data_two";

    // MD5 'name'
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(name.getBytes());
    byte[] md5name = md5.digest();

    // What happens here is beyond me - How would one translate this to PHP?
    byte[] sizeBytes = (size + date).getBytes();
    byte[] tokenBytes = new byte[md5name.length + sizeBytes.length];

    System.arraycopy(sizeBytes, 0, tokenBytes, 0, sizeBytes.length);
    System.arraycopy(md5name, 0, tokenBytes, sizeBytes.length, md5name.length);

    // SHA256
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
    sha256.update(tokenBytes);
    byte[] tokenHash = sha256.digest();

    System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}

这会打印:

LsPw/5/4uKmQfVaU1LRASxG89mgMt7OxX+h7JGRo1ZU=

最终和理想情况下,我喜欢一种快速的方法来使用 PHP 代码获得相同的结果,但我有一种冲动去了解正在发生的事情,而不是仅仅达到预期的结果。

现在试图表明我至少做了一些功课,我不只是在找人为我做我的工作,直到字符串的 MD5 转换,我'我们设法得到一个相同的 base64 编码的 SHA256 字符串 单个字符串 跳过包含 'System.arrayCopy' 位的中间代码块 :

Java代码:

public static void main(String[] args)
        throws
        UnsupportedEncodingException,
        NoSuchAlgorithmException {

    String date = "201603251605";

    // MD5 'name'
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(date.getBytes());
    byte[] md5Date = md5.digest();

    // SHA256
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
    sha256.update(md5Date);
    byte[] tokenHash = sha256.digest();

    System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}

PHP代码:

private function generateToken() {
    $md5Date = md5("201603251605", true);        
    $shaString = hash("sha256", $md5Date, true);

    return base64_encode($shaString); 
}

Java 输出:

mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=

PHP 输出:

mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=

所以根据上面的说法,我的单个字符串的md5和sha可以正常工作,但这不是问题所在。 问题在于了解在 Java 代码中定义多个字符串并将其混合在一起时发生的情况。为什么它看起来过于复杂,在 PHP?

中有简单的方法吗?

有人可以解释一下 MD5 和 SHA256 生成之间发生了什么,以便我可以将其转换为 PHP 代码吗?我试图阅读 Java System.arrayCopy 文档,但我觉得好像我还 experienced/smart 不足以理解那里发生了什么。如果有一个简单的解决方案,我将不胜感激。

当您意识到它实际上做的是多么简单时,您会踢自己的。

<?php
$date = "201603251605";
$name = "some_dummy_data_one";
$size = "some_dummy_data_two";

$md5_name = md5($name, true);

$token_bytes = $size.$date.$md5_name;

$token_hash = hash("sha256", $token_bytes, true);

echo base64_encode($token_hash);

arraycopy 只是一种非常混乱的附加 sizedatemd5name 的方式。为什么 Java 代码如此复杂我不知道。

听起来您在 PHP 中找到了如何操作的答案。 java 代码基本上做同样的事情。这是它在做什么...

// This concatenates size+date and the md5 hash, and then creates a SHA-256 hash from that value.

byte[] sizeBytes = (size + date).getBytes();  //Get byte array of size and date concatenation
byte[] tokenBytes = new byte[md5name.length + sizeBytes.length]; //Create the right size byte array to fit md5 and size+date

System.arraycopy(sizeBytes, 0, tokenBytes, 0, sizeBytes.length); // copies the size+date byte array into the first part of the token bytes byte array.
System.arraycopy(md5name, 0, tokenBytes, sizeBytes.length, md5name.length); //concatenates the md5 hash and size+bytes into the tokenBytes array 

// SHA256
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");//Get the SHA-256 algorithm instance
sha256.update(tokenBytes); // give it a value to hash
byte[] tokenHash = sha256.digest(); // create SHA-256 hash from token bytes