Drupal风格base64编码在java中


Drupal style base64 encoding in java

我正在尝试转换这个:

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

输入字符串-作为十六进制它的这个087b054de375e75979490898fb5ea3d45cee3a0c1a385a76782a4a7cbc3952d21d8b9523175d95d21c5eddb3efebb88733d8cb9de121b11683a41175429e1170

关于随机不符合字符的原因有什么线索吗?

编辑:

在PHP中追踪出错的地方到value |= (int)(input.charAt(i) << (char)16);,这行将值设置为9963593,ord($input[$i])为152,在Java中,当input.charAt(i)为732时,它将值设置为47974473

猜这意味着我没有选择正确的方式将ord($input[$i])转换成Java

我没看到你的代码有bug。Java的字节类型是一个带符号的8位整数,因此它存储值为-128到127。请确保将正确的字节数组传递给函数。这让我很难受。

将字节数组转换为字符串时可能存在问题:

String input = new String(hash);

它将使用你的默认字符集,谁知道那可能是什么。相反,我将使用原始字节数组,这样您就不必担心字符集。

I'd turn this:

value = input.charAt(i++);

这:

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

这是将存储字符(无符号字节)的字节转换为整数的方法。

由于PHP和Java都使用有符号整数,这可能不是区别,但可能是移位操作符。Java(与PHP不同)有两种右移操作符,有符号和无符号:

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

可能需要使用无符号右移操作符?