java中的Drupal风格base64编码

发布于 2024-12-05 11:18:25 字数 2599 浏览 1 评论 0原文

我正在尝试将以下代码转换

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;     
}

为Java: php代码目前有这样的:

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

输入字符串 - 十六进制表示为 this 087b054de375e75979490898fb5ea3d45cee3a0c1a385a76782a4a7cbc3952d2 1d8b9523175d95d21c5eddb3efeb88733d8cb9de121b11683a41175429e1170

关于导致随机不合格字符的任何线索?

编辑:

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

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

I'm trying to convert this:

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 code into Java and currently have this:

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();
}

When supplied with the same thing this happened:

php - 6gL/BBSRbbJS7V.avvpcInZvukU4scZRsdWGwlPCG7R

java - 6gL/BBSRbbJS7V.rvvpcInZvukU4scZRsdWGwlPCG7R

input string - as hex its this 087b054de375e75979490898fb5ea3d45cee3a0c1a385a76782a4a7cbc3952d21d8b9523175d95d21c5eddb3efebb88733d8cb9de121b11683a41175429e1170

Any clues as to what caused the random non conforming character?

EDIT:

Tracing down where it went wrong goes to value |= (int)(input.charAt(i) << (char)16); in PHP this line sets value to be 9963593 with ord($input[$i]) is 152 and in Java it sets it to be 47974473 when input.charAt(i) is 732

Guess this means I havnt chosen the right way of converting ord($input[$i]) into Java

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小墨 2024-12-12 11:18:25

我在你的代码中没有看到错误。 Java 的字节类型是有符号的 8 位整数,因此它存储值 -128 到 127。请确保将正确的字节数组传递到函数中。这让我受益匪浅。

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

String input = new String(hash);

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

我会把这个: 变成

value = input.charAt(i++);

这样:

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

这就是我们如何将存储字符(无符号字节)的字节转换为整数。

I don't see a bug in your code. Java's byte type is a signed 8 bit integer, so it stores values -128 to 127. Please ensure that you're passing the correct byte array into the function. This gets me a lot.

There may be an issue where the byte array is being turned into a string:

String input = new String(hash);

It will use your default character set, and who knows what that may be. Instead, I'd use the raw byte array so you don't have to worry about character sets.

I'd turn this:

value = input.charAt(i++);

Into this:

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

Which is how we convert a byte that is storing a character (unsigned byte) into an integer.

彩扇题诗 2024-12-12 11:18:25

由于 PHP 和 Java 都使用有符号整数,因此这不可能是区别,但可能是移位运算符。 Java(与 PHP 不同)有两种类型的右移运算符,有符号和无符号:

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

您可能需要使用无符号右移运算符吗?

As both PHP and Java use signed integers this can not be the difference, but may be the shift operators. Java has (in difference to PHP) two types of right shift operators, signed and unsigned:

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

May be you need to use unsigned right shift operator?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文