当前位置: 首页 > 知识库问答 >
问题:

PHP包/解包-它能处理可变长度字符串吗

郜卓君
2023-03-14

我一直在试图弄清楚Pack/Unpack的PHP实现是否能够完成Perl版本所能做到的事情。我希望能够在PHP中执行的示例是:

http://perldoc.perl.org/perlpacktut.html#String-长度

# pack a message: ASCIIZ, ASCIIZ, length/string, byte
my $msg = pack( 'Z* Z* C/A* C', $src, $dst, $sm, $prio );
# unpack
( $src, $dst, $sm, $prio ) = unpack( 'Z* Z* C/A* C', $msg );

此Perl代码的作用如下所述:

将两个包代码与斜杠(/)组合将它们与参数列表中的单个值关联。在pack中,参数的长度是根据第一个代码获取和打包的,而参数本身是在斜杠后用模板代码转换后添加的。

i、 e.您可以打包可变长度的字符串,然后在一个步骤中解包,而不必首先计算字符串的长度,然后作为单独的步骤提取。

PHP手册没有提到这个功能,任何试图在解包中插入类似“C/a*”的模式的尝试都会给我带来错误。这是手册中的疏忽还是PHP版本不支持的?

共有1个答案

麹高远
2023-03-14

不幸的是,PHP pack和unpack函数不能像Perl那样提供变量(以null结尾)字符串的自动打包和解包。

为了适应这个功能,考虑将解包函数打包成这样的助手类:

class Packer {
    static function unpack($mask, $data, &$pos) {
        try {
            $result = array();
            $pos = 0;
            foreach($mask as $field) {
                $subject = substr($data, $pos);
                $type = $field[0];
                $name = $field[1];
                switch($type) {
                    case 'N':
                    case 'n':
                    case 'C':
                    case 'c':
                        $temp = unpack("{$type}temp", $subject);
                        $result[$name] = $temp['temp'];
                        if($type=='N') {
                            $result[$name] = (int)$result[$name];
                        }

                        $pos += ($type=='N' ? 4 : ($type=='n' ? 2 : 1));
                        break;
                    case 'a':
                        $nullPos = strpos($subject, "\0") + 1;
                        $temp = unpack("a{$nullPos}temp", $subject);
                        $result[$name] = $temp['temp'];
                        $pos += $nullPos;
                        break;
                }
            }
            return $result;
        } catch(Exception $e) {
            $message = $e->getMessage();
            throw new Exception("unpack failed with error '{$message}'");
        }
    }
}

请注意,这个函数并没有实现所有的解包类型,只是作为一个例子。

 类似资料:
  • 问题内容: 我正在尝试掌握Python 3中二进制数据的打包和拆包。除了一个问题外,它实际上并不难理解: 如果我有可变长度的文本字符串,并且想要以最优雅的方式打包和解压缩该怎么办? 据我所知,我只能直接解压缩固定大小的字符串吗?在那种情况下,是否有任何优雅的方法来解决此限制,而无需填充很多不必要的零? 问题答案: 该模块仅支持固定长度的结构。对于变长字符串,您可以选择以下任一种: 动态构造格式字符

  • 问题内容: 我正在从另一台服务器下载CSV文件,作为供应商的数据提要。 我正在使用curl获取文件的内容,并将其保存到名为的变量中。 我可以很好地达到那部分,但是我尝试通过爆炸并获得行数组,但是失败并出现“内存不足”错误。 我,大约是3050万个字符。 我需要处理这些值并将它们插入数据库。为了避免内存分配错误,我该怎么办? 问题答案: PHP令人窒息,因为它耗尽了内存。不要使用curl来用文件的内

  • 本文向大家介绍php可变长参数处理函数详解,包括了php可变长参数处理函数详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php可变长参数处理函数。分享给大家供大家参考,具体如下: 与C++一样,PHP中也可以对含有可变参数的函数进行处理,道理都一样,需要函数来专门处理参数列表。PHP中提供了三个相关的函数: 1. func_num_args()  -- 返回传递给函数的参数个数 in

  • 问题内容: 数据如下所示: 我希望它看起来像这样: 摆脱一个或另一个很简单。 这: 给我这样的建议:倡议:可信来源倡议:及时的倡议:数据库规范化 还有这个: 给我这个: 很难弄清楚如何将两者结合起来。 问题答案: 只是使用怎么样? 或者,如果您不知道前缀有多长时间: 这是一个。

  • 问题内容: 我有以下字符串: 如果仅打印此内容,它将输出如下内容(当然不会“按字面意思”打印): 调用方法时,我想获取新行()字符之间的所有字符串,甚至最后还有空字符串。 例如,如果我今天这样做: 我希望它像这样打印出来(输出A): 当前,它以这种方式打印(输出B),并且所有结尾的空字符串都将被跳过: 如何使方法像输出A那样包含空字符串?我当然可以编写多行代码,但是想知道,在我浪费时间尝试实现这一

  • 问题内容: 我有一个长度为141个字符的字符串。使用以下代码,如果字符串大于或小于140,我有一条语句返回一条消息。 我在$ message上使用了var_dump,它显示的字符串是。这是我的问题:当我将语句的编号更改为和时,尽管字符串大于131,它仍然返回第一条消息。 无论我使用的数字少于141,我总是得到“没有比赛”。回到我身边。 问题答案: 尝试使用通用语法: