使用不是2

时间:2017-04-04 12:25:03

标签: algorithm bit-manipulation base

Base64将三个8位字符编码到四个(base-64)6位“字符”上。 Base64是有效的,因为它使用基数(64)和指数(4)恰好匹配基数10指数2(24):3x8 = 4x6 = 24和2 24 = 64 < SUP> 4 = 16777216。

似乎没有基础/指数组合导致的值与2的基数10指数完全匹配(特别是2 n 对于任何0&lt; n &lt; 256),除了base32,base64和base128(以及更难以实际使用的base4,base8,base16,base256,base512等)。 请参阅最后一个代码块以获取匹配指数的完整列表!

使用base92的例子,92 2 = 8464,最接近的10的指数为2 13 = 8192.8464-8192 = 272指数在base92方面可用(如果我理解正确的话)是不可能利用的。  (2 19 = 524288&lt; 91 3 = 753571&lt; 2 20 = 1048576,但2 20 - 91 3 = 295005.272是明显的赢家。)

在今天下午早些时候考虑这些损失问题时,我遇到了一个有趣的问题。如果我一次查看输入14位,并且我遇到了像00100000 11111111这样的输入序列,我可以将其解释为10000011111111或8447,并在区域8193&lt; n &lt; 8464,否则无法访问!但是,一旦我到达10000100010001,8465,我就需要回到使用7位编码。这使得这种方法对输入敏感,并且实际上仅对起始字节为10000100(132,ASCII'Z')的双字节序列有用。我宁愿我的编码器不是输入敏感的。

我有两个问题:

  1. 我对base- n 编码的理解似乎是正确的吗?除了维基百科页面,我还可以去哪里了解它?

  2. 我是否可以使用任何技巧或技巧来提高base32 / 64/12以外的任意基础的 n 压缩效率?

  3. 参考

    除此之外的所有内容都不需要阅读以回答我的问题。

    这个小的PHP脚本计算每个可能的基数^指数(对于0&lt; base&lt; 513和2&lt; exponent&lt; 257,两者都是任意选择的)并且每个可能的指数为2 n (对于0 < n &lt; 256)。然后它减去两个计算的结果,并按升序列出结果。

    它是为Linux编写的,但如果你注释掉fprintf()调用(包含一些转义序列),它应该可以在Windows上正常运行。

    请注意,此程序将生成30,145行输出:)

    <?php
    
    $c = 0;
    $op = 0;
    
    for ($i = 3; $i < 513; $i++) {
        for ($j = 2; $j < 257; $j++) {
            $p = ($c * 100) / 33835;
            if ($p > $op + 5 || $p == 100) {
                fprintf(STDERR, "\rgen:  %2.1f%%", $p);
                $op = $p;
            }
            if ($i >= 2 ** 32 || $j >= 2 ** 32 || $i ** $j >= 2 ** 32) continue;
            for ($k = 1; $k < 33; $k++) {
                $x = $i ** $j - 2 ** $k;
                if ($x < 0) continue;
                if (!isset($a[$x])) $a[$x] = [];
                $a[$x][] = [ $i, $j, $k, $i ** $j, 2 ** $k, (float)sprintf("%2.1f", ((2 ** $k) / ($i ** $j)) * 100) ];
                $c++;
            }
        }
    }
    
    foreach ($a as $i => $_) {
        if ($i < 0) {
            print "\r64-bit machine required\n";
            die;
        }
    }
    
    $q = $op = $c = 0;
    foreach ($a as $i => $_) {
        $p = ($c * 100) / 28013;
        if ($p > $op + 5 || $p == 100) {
            fprintf(STDERR, "\rsort: %2.1f%%", $p);
            $op = $p;
        }
        $c++;
        uasort($a[$i], function($a, $b) {
            return $a[0] < $b[0];
        });
    }
    
    fprintf(STDERR, "\rsort root\e[K");
    uksort($a, function($a, $b) {
        return $a > $b;
    });
    
    fprintf(STDERR, "\r\e[K");
    $l = 0;
    foreach ($a as $i => $z) {
        foreach ($z as $x) {
            print
                sprintf("%5d %5.1f%%", $l++, $x[5])
                .' ('.$x[0].'^'.$x[1].'='.sprintf("%.0f", $x[0] ** $x[1]).')'
                .'-(2^'.$x[2].'='.(2 ** $x[2]).')'
                .'='.$i
                ."\n";
    
        }
    }
    

    如本问题开头第二段末尾所述,这里是完全匹配2 n 为0&lt; <的指数组合的完整列表EM>名词&LT; 256

    格式为:行号; (2 ^ n)/(base ^ exponent)以百分比表示; (基^指数=结果) - (2 ^指数)=距离

    注意第9行的base64.Base92在上面程序的完整输出的第200行。

        0 100.0% (512^3=134217728)-(2^27=134217728)=0
        1 100.0% (512^2=262144)-(2^18=262144)=0
        2 100.0% (256^3=16777216)-(2^24=16777216)=0
        3 100.0% (256^2=65536)-(2^16=65536)=0
        4 100.0% (128^4=268435456)-(2^28=268435456)=0
        5 100.0% (128^3=2097152)-(2^21=2097152)=0
        6 100.0% (128^2=16384)-(2^14=16384)=0
        7 100.0% (64^3=262144)-(2^18=262144)=0
        8 100.0% (64^2=4096)-(2^12=4096)=0
        9 100.0% (64^4=16777216)-(2^24=16777216)=0
       10 100.0% (64^5=1073741824)-(2^30=1073741824)=0
       11 100.0% (32^6=1073741824)-(2^30=1073741824)=0
       12 100.0% (32^5=33554432)-(2^25=33554432)=0
       13 100.0% (32^4=1048576)-(2^20=1048576)=0
       14 100.0% (32^3=32768)-(2^15=32768)=0
       15 100.0% (32^2=1024)-(2^10=1024)=0
       16 100.0% (16^2=256)-(2^8=256)=0
       17 100.0% (16^7=268435456)-(2^28=268435456)=0
       18 100.0% (16^6=16777216)-(2^24=16777216)=0
       19 100.0% (16^5=1048576)-(2^20=1048576)=0
       20 100.0% (16^4=65536)-(2^16=65536)=0
       21 100.0% (16^3=4096)-(2^12=4096)=0
       22 100.0% (8^10=1073741824)-(2^30=1073741824)=0
       23 100.0% (8^8=16777216)-(2^24=16777216)=0
       24 100.0% (8^7=2097152)-(2^21=2097152)=0
       25 100.0% (8^6=262144)-(2^18=262144)=0
       26 100.0% (8^5=32768)-(2^15=32768)=0
       27 100.0% (8^4=4096)-(2^12=4096)=0
       28 100.0% (8^3=512)-(2^9=512)=0
       29 100.0% (8^2=64)-(2^6=64)=0
       30 100.0% (8^9=134217728)-(2^27=134217728)=0
       31 100.0% (4^3=64)-(2^6=64)=0
       32 100.0% (4^8=65536)-(2^16=65536)=0
       33 100.0% (4^4=256)-(2^8=256)=0
       34 100.0% (4^5=1024)-(2^10=1024)=0
       35 100.0% (4^6=4096)-(2^12=4096)=0
       36 100.0% (4^7=16384)-(2^14=16384)=0
       37 100.0% (4^13=67108864)-(2^26=67108864)=0
       38 100.0% (4^9=262144)-(2^18=262144)=0
       39 100.0% (4^10=1048576)-(2^20=1048576)=0
       40 100.0% (4^11=4194304)-(2^22=4194304)=0
       41 100.0% (4^12=16777216)-(2^24=16777216)=0
       42 100.0% (4^14=268435456)-(2^28=268435456)=0
       43 100.0% (4^15=1073741824)-(2^30=1073741824)=0
       44 100.0% (4^2=16)-(2^4=16)=0
    

1 个答案:

答案 0 :(得分:0)

base128无效,因为您必须使用大于'128'的字符巫婆代码。对于> = 128 chrome的字符女巫代码,请发送两个字节...(因此,字符串女巫在发送时将其中的1MB字符更改为2MB字节...因此您失去了所有收益)。对于base64字符串,不会出现这种现象(因此,我们只松动了〜33%)。更多详细信息here in "update" section