开发者

Drupal style base64 encoding in java

开发者 https://www.devze.com 2023-04-06 09:40 出处:网络
I\'m trying to convert this: function _password_itoa64() { return \'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\';

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) 开发者_StackOverflow社区& 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


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.


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?

0

精彩评论

暂无评论...
验证码 换一张
取 消