Кодировка base64 в стиле Drupal в Java - PullRequest
2 голосов
/ 19 сентября 2011

Я пытаюсь преобразовать это:

function _password_itoa64() {
  return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
}

function _password_base64_encode($input, $count) {
  $output = '';
  $i = 0;
  $itoa64 = _password_itoa64();
  do {
    $value = ord($input[$i++]);
    $output .= $itoa64[$value & 0x3f];
    if ($i < $count) {
      $value |= ord($input[$i]) << 8;
    }
    $output .= $itoa64[($value >> 6) & 0x3f];
    if ($i++ >= $count) {
      break;
    }
    if ($i < $count) {
      $value |= ord($input[$i]) << 16;
    }
    $output .= $itoa64[($value >> 12) & 0x3f];    
    if ($i++ >= $count) {
      break;
    }
    $output .= $itoa64[($value >> 18) & 0x3f];
  } while ($i < $count);       

  return $output;     
}

PHP-код в Java и в настоящее время имеет это:

private static String _password_itoa64(){
    return "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
}

private String _password_base64_encode(byte[] hash, int count){
    StringBuffer output = new StringBuffer();
    String input = new String(hash);
    String itoa64 = _password_itoa64();
        int i = 0, value;
        do {
            value = input.charAt(i++);
            output.append(itoa64.charAt(value & 0x3f));
            if (i < count) {
                value |= (int)(input.charAt(i) << (char)8);
            }
            output.append(itoa64.charAt((value >> 6) & 0x3f));
            if (i++ >= count) {
                break;
            }
            if (i < count) {
                value |= (int)(input.charAt(i) << (char)16);
            }
            output.append(itoa64.charAt((value >> 12) & 0x3f));
            if (i++ >= count) {
                break;
            }
            output.append(itoa64.charAt((value >> 18) & 0x3f));
        }
        while (i < count);

        return output.toString();
}

Когда получено то же самое, это произошло:

php - 6gL/BBSRbbJS7V.avvpcInZvukU4scZRsdWGwlPCG7R

Java - 6gL/BBSRbbJS7V.rvvpcInZvukU4scZRsdWGwlPCG7R

строка ввода - в шестнадцатеричном виде это 087b054de375e75979490898fb5ea3d45cee3a0c1a385a76782a4a7cbc3952d21d8b9523175d95d21c5eddb3efebb88733d8cb9de1217075429

Есть какие-нибудь подсказки относительно того, что вызвало случайного несоответствующего персонажа?

EDIT:

В поисках того, что пошло не так, в PHP value |= (int)(input.charAt(i) << (char)16); эта строка устанавливает значение равным 9963593 с ord($input[$i]) равным 152, а в Java оно устанавливает 47974473, когда input.charAt(i) равно 732

Полагаю, это означает, что я выбрал правильный способ преобразования ord($input[$i]) в Java

Ответы [ 2 ]

1 голос
/ 19 сентября 2011

Я не вижу ошибки в вашем коде.Тип байта Java представляет собой 8-разрядное целое число со знаком, поэтому он хранит значения от -128 до 127. Убедитесь, что в функцию передан правильный байтовый массив.Это мне очень помогает.

Может быть проблема, когда байтовый массив превращается в строку:

String input = new String(hash);

Он будет использовать ваш набор символов по умолчанию, и кто знает, что этоможет быть.Вместо этого я бы использовал необработанный байтовый массив, чтобы вам не приходилось беспокоиться о наборах символов.

Я бы превратил это:

value = input.charAt(i++);

В это:

value := (int)(hash[i++] & 0xFF);

Именно так мы конвертируем байт, хранящий символ (байт без знака), в целое число.

0 голосов
/ 19 сентября 2011

Поскольку и в PHP, и в Java используются целые числа со знаком, разница не может быть, но могут быть операторы сдвига.В Java (в отличие от PHP) есть два типа операторов смещения вправо, со знаком и без знака:

<<  Signed left shift
>>  Signed right shift
>>> Unsigned right shift

Может быть, вам нужно использовать беззнаковый оператор смещения вправо?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...