首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在PHP中使用bits

在PHP中使用bits
EN

Stack Overflow用户
提问于 2013-02-27 17:42:39
回答 1查看 2K关注 0票数 3

假设我想在PHP中存储一个8个单词的序列,并且我不想使用压缩。

由于只有8个字,我可以给每个字分配一个二进制值,然后将这些二进制值存储在一个文件中,而不是ascii字。

可能的二进制值为:

代码语言:javascript
运行
复制
000, 001, 010, 011, 100, 101, 110, 111

这将是更高效的解析,因为:(1)现在每个单词的大小都相同,(2)它占用的空间要少得多。

我的问题是:

我如何在PHP中做到这一点?我如何将二进制值赋给某个东西,然后将其写入文件(按我想要的方式写入位),然后再读一遍?

我想这样做的原因是为了创建一个高效的索引系统。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-28 12:33:33

首先,如果您想压缩数据,可以使用php内置函数来压缩数据,比如gzip扩展。

但根据您的要求,我已经准备了一个如何在PHP中完成此操作的示例。它并不完美,只是一个微不足道的实现。如果我使用每个整数的位30和32之间的间隔,压缩率可能会更好。可能会添加这个功能...然而,我使用了32位无符号整数来支持字节,因为它们的损失是每32位2位,而不是每字节2位。

首先,我们准备包含关系词=>十进制数的查找表,它是编码表:

代码语言:javascript
运行
复制
<?php

// coding table
$lookupTable = array (
//  'word0' => chr(0), // reserved for 0 byte gap in last byte
    'word1' => chr(1),
    'word2' => chr(2),
    'word3' => chr(3),
    'word4' => chr(4),
    'word5' => chr(5),
    'word6' => chr(6),
    // reserve one word for white space
    ' ' => chr(7)
);

然后是压缩函数:

代码语言:javascript
运行
复制
/**
 *
 */
function _3bit_compress($text, $lookupTable) {

    echo 'before compression                  : ' . strlen($text) . ' chars', PHP_EOL;

    // first step is one byte compression using the lookup table
    $text = strtr($text, $lookupTable);
    echo 'after one byte per word compression : ' . strlen($text) . ' chars', PHP_EOL;

    $bin = ''; // the result
    $carrier = 0; // 32 bit usingned int can 'carry' 10 words in 3 bit notation

    for($c = 0; $c < strlen($text); $c++) {
        $triplet = $c % 10;
        // every 30 bits we add the 4byte unsigned integer to $bin.
        // please read the manual of pack
        if($triplet === 0 && $carrier !== 0) {
            $bin .= pack('N', $carrier);
            $carrier = 0;
        }

        $char = $text[$c];
        $carrier  <<= 3; // make space for the the next 3 bits
        $carrier += ord($char); // add the next 3 bit pattern
        // echo $carrier, ' added ' . ord($char), PHP_EOL;
    }
    $bin .= pack('N', $carrier); // don't forget the remaining bits
    echo 'after 3 bit compression             : ' . strlen($bin) . ' chars', PHP_EOL;
    return $bin;
}

和解压缩函数:

代码语言:javascript
运行
复制
/**
 *
 */
function _3_bit_uncompress($compressed, $lookupTable) {
    $len = strlen($compressed);
    echo 'compressed length:            : ' . $len . ' chars', PHP_EOL;

    $i = 0;
    $tmp = '';
    $text = '';
    // unpack string as 4byte unsigned integer
    foreach(unpack('N*', $compressed) as $carrier) {
        while($i < 10) {
            $code = $carrier & 7; // get the next code
            // echo $carrier . ' ' . $code, PHP_EOL;
            $tmp = chr($code) . $tmp;
            $i++;
            $carrier >>= 3; // shift forward to the next 3 bits
        }
        $i = 0;
        $text = $text . $tmp;
        $tmp = '';
    }
    // reverse translate from decimal codes to words
    return strtr($text, array_flip($lookupTable));
}

现在是测试函数的时候了:)

代码语言:javascript
运行
复制
$original = <<<EOF
word1 word2 word3 word4 word5 word6 word1 word3 word3  word2
EOF;


$compressed = _3bit_compress($original, $lookupTable);
$restored = _3_bit_uncompress($compressed, $lookupTable);

echo 'compressed size: ' . round(strlen($compressed) * 100 / strlen($original), 2) . '%', PHP_EOL;

echo 'Message before compression  : ' . $original, PHP_EOL;
echo 'Message after decompression : ' . $restored, PHP_EOL;

这个例子应该会告诉你:

代码语言:javascript
运行
复制
before compression                  : 60 chars
after one byte per word compression : 20 chars
after 3 bit compression             : 8 chars
compressed length:            : 8 chars
compressed size: 13,33%
Message before compression  : word1 word2 word3 word4 word5 word6 word1 word3 word3  word2
Message after decompression : word1 word2 word3 word4 word5 word6 word1 word3 word3  word2

如果我们用很长的单词测试,压缩率当然会变得更好:

代码语言:javascript
运行
复制
before compression                  : 112 chars
after one byte per word compression : 16 chars
after 3 bit compression             : 8 chars
compressed length:            : 8 chars
compressed size: 7,14%
Message before compression  : wooooooooord1 wooooooooord2 wooooooooord2 wooooooooord3 wooooooooord1 wooooooooord2 wooooooooord2 wooooooooord3 
Message after decompression : wooooooooord1 wooooooooord2 wooooooooord2 wooooooooord3 wooooooooord1 wooooooooord2 wooooooooord2 wooooooooord3 
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15108768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档