简体   繁体   English

有效的解决方案:在php中使用base32编码

[英]effective solution: base32 encoding in php

I am looking for a base32 function/class for php. 我正在为php寻找一个base32函数/类。 the different classes and function that i found are all very ineffective. 我发现的不同类别和功能都非常无效。 I ran a benchmark and came to the following result: 我运行了一个基准测试并得出以下结果:

10000 decodings: 10000个解码:

base32: 2.3273 seconds base32:2.3273秒

base64: 0.0062 seconds base64:0.0062秒

The base32 class which I have used is: 我使用的base32类是:

http://www.php.net/manual/en/function.base-convert.php#102232 http://www.php.net/manual/en/function.base-convert.php#102232

Is there any way which is simpler? 有什么方法更简单吗?

The reason why I want to use base32 is that it is not case sensitive and as a result I have no problems any more regarding url parameters which on some system (eg email systems) are always converted to lowercase letters. 我想使用base32的原因是它不区分大小写,因此我对url参数没有任何问题,这些参数在某些系统(例如电子邮件系统)上总是转换为小写字母。

If you have a better alternative for lowercase encoding, I would also love to hear them. 如果您有更好的小写编码替代方案,我也很乐意听到它们。

For Base32 in PHP, you can try my implementation here: 对于PHP中的Base32,您可以在此处尝试我的实现:

https://github.com/ademarre/binary-to-text-php https://github.com/ademarre/binary-to-text-php

Copied from the Base32 example in the README file: 从README文件中的Base32示例复制:

// RFC 4648 base32 alphabet; case-insensitive
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
$encoded = $base32->encode('encode this');
// MVXGG33EMUQHI2DJOM======

It's not slow, and it may or may not be faster than the class you benchmarked, but it will not be as fast as a built-in PHP function like base64_encode() . 它并不慢,它可能会或可能不会比你的基准测试类快,但它不会像base64_encode()这样的内置PHP函数那么快。 If that is very important to you, and you don't really care about Base32 encoding, then you should just use hexadecimal. 如果这对您非常重要,并且您并不真正关心Base32编码,那么您应该只使用十六进制。 You can encode hexadecimal with native PHP functions, and it is case-insensitive. 您可以使用本机PHP函数对十六进制进行编码,并且它不区分大小写。

$encoded = bin2hex('encode this'); // 656e636f64652074686973
$decoded = pack('H*', $encoded);   // encode this

// Alternatively, as of PHP 5.4...
$decoded = hex2bin($encoded);      // encode this

The downside to hexadecimal is that there is more data inflation compared to Base32. 十六进制的缺点是与Base32相比,数据通胀率更高。 Hexadecimal inflates the data 100%, while Base32 inflates the data about 60%. 十六进制使数据膨胀100%,而Base32将数据膨胀约60%。

Try this: https://github.com/bbars/utils/blob/master/php-base32-encode-decode/Base32.php 试试这个: https//github.com/bbars/utils/blob/master/php-base32-encode-decode/Base32.php

Uses case-insesitive alpabet [0-9, av] and works faster than Base2n(5) : 使用case-initive的alpabet [0-9, av]并且比Base2n(5)工作得更快:

size   | Base32::encode  | Base32::decode  | $base2n->encode  | $base2n->decode
-------------------------------------------------------------------------------
1      | 0.0000331401825 | 0.0000088214874 | 0.0002369880676  | 0.0001671314240
2      | 0.0000050067902 | 0.0000040531158 | 0.0000100135803  | 0.0000081062317
4      | 0.0000050067902 | 0.0000059604645 | 0.0000097751617  | 0.0000100135803
8      | 0.0000078678131 | 0.0000100135803 | 0.0000131130219  | 0.0000140666962
16     | 0.0000128746033 | 0.0000178813934 | 0.0000250339508  | 0.0000250339508
32     | 0.0000238418579 | 0.0000319480896 | 0.0000441074371  | 0.0000472068787
64     | 0.0001170635223 | 0.0000629425049 | 0.0000870227814  | 0.0000259876251
128    | 0.0000879764557 | 0.0001208782196 | 0.0001959800720  | 0.0001759529114
256    | 0.0001969337463 | 0.0002408027649 | 0.0004429817200  | 0.0003459453583
512    | 0.0003631114960 | 0.0004880428314 | 0.0021460056305  | 0.0006039142609
1024   | 0.0014970302582 | 0.0009729862213 | 0.0108621120453  | 0.0015850067139
2048   | 0.0013530254364 | 0.0018491744995 | 0.0312080383301  | 0.0027630329132
4096   | 0.0027470588684 | 0.0038080215454 | 0.1312029361725  | 0.0064430236816
8192   | 0.0064270496368 | 0.0086290836334 | 0.5233020782471  | 0.0121779441833
16384  | 0.0112588405609 | 0.0167109966278 | 2.0316259860992  | 0.0277659893036
32768  | 0.0235319137573 | 0.0335960388184 | 11.6220989227295 | 0.0498571395874
65536  | 0.0478749275208 | 0.0648550987244 |                  |                
131072 | 0.1030550003052 | 0.1504058837891 |                  |                
262144 | 0.1995100975037 | 0.2654621601105 |                  |                
524288 | 0.3903131484985 | 0.5326008796692 |                  |                

You can try these functions I adapted from bbars and crockford : 你可以尝试我改编自bbarscrockford的这些功能:

function crockford32_encode($data) {
    $chars = '0123456789abcdefghjkmnpqrstvwxyz';
    $mask = 0b11111;

    $dataSize = strlen($data);
    $res = '';
    $remainder = 0;
    $remainderSize = 0;

    for($i = 0; $i < $dataSize; $i++) {
        $b = ord($data[$i]);
        $remainder = ($remainder << 8) | $b;
        $remainderSize += 8;
        while($remainderSize > 4) {
            $remainderSize -= 5;
            $c = $remainder & ($mask << $remainderSize);
            $c >>= $remainderSize;
            $res .= $chars[$c];
        }
    }
    if($remainderSize > 0) {
        $remainder <<= (5 - $remainderSize);
        $c = $remainder & $mask;
        $res .= $chars[$c];
    }

    return $res;
}

function crockford32_decode($data) {
    $map = [
        '0' => 0,
        'O' => 0,
        'o' => 0,
        '1' => 1,
        'I' => 1,
        'i' => 1,
        'L' => 1,
        'l' => 1,
        '2' => 2,
        '3' => 3,
        '4' => 4,
        '5' => 5,
        '6' => 6,
        '7' => 7,
        '8' => 8,
        '9' => 9,
        'A' => 10,
        'a' => 10,
        'B' => 11,
        'b' => 11,
        'C' => 12,
        'c' => 12,
        'D' => 13,
        'd' => 13,
        'E' => 14,
        'e' => 14,
        'F' => 15,
        'f' => 15,
        'G' => 16,
        'g' => 16,
        'H' => 17,
        'h' => 17,
        'J' => 18,
        'j' => 18,
        'K' => 19,
        'k' => 19,
        'M' => 20,
        'm' => 20,
        'N' => 21,
        'n' => 21,
        'P' => 22,
        'p' => 22,
        'Q' => 23,
        'q' => 23,
        'R' => 24,
        'r' => 24,
        'S' => 25,
        's' => 25,
        'T' => 26,
        't' => 26,
        'V' => 27,
        'v' => 27,
        'W' => 28,
        'w' => 28,
        'X' => 29,
        'x' => 29,
        'Y' => 30,
        'y' => 30,
        'Z' => 31,
        'z' => 31,
    ];

    $data = strtolower($data);
    $dataSize = strlen($data);
    $buf = 0;
    $bufSize = 0;
    $res = '';

    for($i = 0; $i < $dataSize; $i++) {
        $c = $data[$i];
        if(!isset($map[$c])) {
            throw new \Exception("Unsupported character $c (0x".bin2hex($c).") at position $i");
        }
        $b = $map[$c];
        $buf = ($buf << 5) | $b;
        $bufSize += 5;
        if($bufSize > 7) {
            $bufSize -= 8;
            $b = ($buf & (0xff << $bufSize)) >> $bufSize;
            $res .= chr($b);
        }
    }

    return $res;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM