2016-03-25 3 views
1

Мне предоставлен фрагмент кода, который описывает «алгоритм» для генерации маркера. Этот код написан на Java и работает корректно. Данный код Java должен оставаться таким же, как и, однако мое требование состоит в том, чтобы иметь тот же «алгоритм», который используется в приложении PHP, и мне трудно получить тот же результат.Разница между Java и PHP

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/л.с выход/m9sD6FdzM6LZHIORtr260 =

РНР:

mEkkRlBkwyoWFMsA + V/л.с/m9sD6FdzM6LZHIORtr260 =

Итак, согласно вышеизложенному, мой md5 и sha одной строки отлично работает, но это не проблема. Проблема заключается в понимании того, что происходит, когда несколько строк определены и размножаются в коде Java. Почему это кажется чрезмерно сложным и есть простой способ сделать это в PHP?

Не могли бы вы объяснить, что происходит между поколениями MD5 и SHA256, чтобы я мог перевести его на PHP-код? Я попытался прочитать документацию Java System.arrayCopy, но мне кажется, что я недостаточно опытен и умен, чтобы понять, что там происходит. Если это будет простое решение, я бы очень его оценил.

+0

Не понимаю вопрос на самом деле. Хотя у вас много слов. Вы, кажется, задаете вопрос, а затем решаете его. Так в чем же вопрос? – KyleK

+2

@KyleK он просто хочет знать, что делает эта средняя часть кода Java. Посмотрите на его встроенные комментарии. – CodeGodie

+0

@KyleK, есть много слов по причине. Чтение помогает;) – snh

ответ

1

Вы будете пинать себя, когда поймете, насколько просто то, что он на самом деле делает.

<?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 это просто довольно запутанный способ добавления size, date и md5name. Почему Java-код настолько сложный, что я понятия не имею.

+1

Я отвечаю на свою реальную учетную запись - не совсем уверен, почему я вошел в новую учетную запись. Вы правы - и я по праву дал себе крупную лицевую ладонь. Спасибо! – snh

1

Похоже, вы получили ответ, как это сделать на 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 
+0

Спасибо за дополнительную информацию Dustin. Возможно, вы видите причину, почему этот маршрут был принят вместо того, чтобы просто конкатенировать строки и MD5 как строку? Кажется, что разработчик ушел с пути, чтобы сделать его излишне сложным, ИМО. – snh

+0

Если бы мне пришлось угадать, я бы сказал, что в какой-то момент они высевали хеш с более безопасным «случайным» значением, а не строкой и строкой даты, а затем потребовалось статическое строковое значение, возможно, для тестирования? Если раньше они использовали что-то более безопасное, они хотели бы использовать байтовые значения. Все, что вам нужно с этим кодом, чтобы узнать значение токена, это размер, имя и дата. – Dustin

Смежные вопросы