phpass';s定制的Base64编码器:它比Base64有名称/优势吗?

phpass';s定制的Base64编码器:它比Base64有名称/优势吗?,php,algorithm,encoding,base64,bit-manipulation,Php,Algorithm,Encoding,Base64,Bit Manipulation,使用一个奇怪的(对我来说)算法来进行base64编码。在映射到可打印字符之前,线性地分块6个比特以产生每个八位组encode64将位左右移动: input bit location: abcdefgh ijklmnop qrstuvwx base64 bit location: ..abcdef ..ghijkl ..mnopqr ..stuvwx encode64 bit location: ..cdefgh ..mnopab ..wxijkl ..qrstuv 这个算法是众所周知

使用一个奇怪的(对我来说)算法来进行base64编码。在映射到可打印字符之前,线性地分块6个比特以产生每个八位组
encode64
将位左右移动:

input bit location:    abcdefgh ijklmnop qrstuvwx
base64 bit location:   ..abcdef ..ghijkl ..mnopqr ..stuvwx
encode64 bit location: ..cdefgh ..mnopab ..wxijkl ..qrstuv
这个算法是众所周知的吗?除了向后兼容之外,为什么选择它而不是Base64

下面我重写了它以澄清算法:

function encode64($input, $bytesToProcess)
{
    // convert to array of ints
    for ($i = 0; $i < $bytesToProcess; $i++) {
        $bytes[] = ord($input[$i]);
    }

    $octets = array();
    $i = 0;
    do {
        $value = $bytes[$i++];
        $octets[] = $value & 0x3f;
        if ($i < $bytesToProcess) {
            $value |= $bytes[$i] << 8;
        }
        $octets[] = ($value >> 6) & 0x3f;
        if ($i++ >= $bytesToProcess) {
            break;
        }
        if ($i < $bytesToProcess) {
            $value |= $bytes[$i] << 16;
        }
        $octets[] = ($value >> 12) & 0x3f;
        if ($i++ >= $bytesToProcess) {
            break;
        }
        $octets[] = ($value >> 18) & 0x3f;
    } while ($i < $bytesToProcess);

    return array_map(function ($i) {
        return str_pad(base_convert($i, 10, 2), 6, '0', STR_PAD_LEFT);
    }, $octets);
}

var_export(encode64("Man", 3));
函数encode64($input,$bytesToProcess)
{
//转换为整数数组
对于($i=0;$i<$bytesToProcess;$i++){
$bytes[]=ord($input[$i]);
}
$octets=array();
$i=0;
做{
$value=$bytes[$i++];
$octets[]=$value&0x3f;
如果($i<$bytesToProcess){
$value |=$bytes[$i]>6)&0x3f;
如果($i++>=$bytesToProcess){
打破
}
如果($i<$bytesToProcess){
$value |=$bytes[$i]>12)&0x3f;
如果($i++>=$bytesToProcess){
打破
}
$octets[]=($value>>18)和0x3f;
}而($i<$bytesToProcess);
返回数组映射(函数($i){
返回stru-pad(基本转换($i,10,2),6,'0',stru-pad-LEFT);
}(八位字节);
}
var_出口(编码64(“男人”,3));

(更新以准确指示每个输入位的移动位置)

encode64在a-zA-Z0-9旁边使用“.”和“/”。Base64使用“+”和“/”。此外,“.”和“/”映射到0和1,而“+”和“/”映射到Base64中的62和63

UUencode使用字母、数字和许多标点符号与没有大写字母的系统兼容


我不熟悉encode64。使用它的唯一原因是您使用的环境中不允许使用“+”。但是,您可以使用Base64并执行str_替换。

encode64()
看起来就像是标准base64的一个实现,它以相反的顺序计算位,并使用不同的字符集——例如,如果你眯着眼睛看对了,它会选择第一个字节的最后6位作为第一个输出字符。这可能只是一个错误;这对安全性或性能没有好处n这样做(以及与PHP本机相比的一些性能缺陷).

在我看来,这就像是在两端进行字节交换:颠倒3个输入字节的顺序,将它们分为6位片段,然后颠倒输出字节的顺序。我认为这会产生相同的效果,是的。无论哪种方式,在过程中的某个点上都是颠倒的。将其描述为“crypt()的*nix标准”感谢您提出这个问题!我曾尝试在Go中实现与Drupal兼容的身份验证,并将此包用于base64编码:但创建的结果与Drupal中保存的哈希不匹配。只有在重新实现Go的base64包之后,我才像Drupals base64Encode()中那样进行奇怪的位移动哈希匹配。问题是,为什么Drupal或phpass开发人员使用特殊的方式进行base64编码。真的错了吗?我将在Drupal Stackexchange中提出这个问题。