【问题标题】:010 Editor template: Parsing 7-bit encoded int for length-prefixed string010 编辑器模板:为长度前缀字符串解析 7 位编码的 int
【发布时间】:2017-08-09 22:02:17
【问题描述】:

010 Editor 模板(类似 C/C++ 的语法)中,我想解析一个用 Microsoft .Net 的 BinaryWriter 类编写的字符串,如下所示:

myBinaryWriter.Write("hello");

这会写出一个以长度为前缀的字符串,其中长度用Write7BitEncodedInt 编码。这里是写长度的.Net源码,供参考:

// Write out an int 7 bits at a time.  The high bit of the byte, 
// when on, tells reader to continue reading more bytes. 
uint v = (uint) value;   // support negative numbers
while (v >= 0x80) { 
    Write((byte) (v | 0x80));
    v >>= 7;
}
Write((byte)v); 

010 编辑器模板语法中的结构定义如何解析这样编码的字符串?

【问题讨论】:

  • 您的问题是否在于理解特定脚本语言的编码或制定解码器?在 C 语言中,你会按照unsigned c, v = 0, b = 0; do v |= (c = Read()) & 0x7F) << b; while(b += 7, c & 0x80); 的方式做一些事情。我不知道它是否或如何为您的 HEX 编辑器转换为解析器脚本,但鉴于 C 标记,我想这可能是一个起点。
  • 你有什么问题?
  • 我想我了解编码,但我既不熟悉 C 也不熟悉位操作和指针操作。如果它不使用太多不受支持的功能,我认为我可以将纯 C 解决方案转换为编辑器的脚本语言。例如,不支持指针,但存在以 null 结尾的“字符串”类型...

标签: c string data-structures


【解决方案1】:

这是一种将 .net 二进制字符串解析为 010 编辑器二进制模板的粗略方法,它处理 1 和 2 字节长度的前缀,但使用循环将其扩展为更长的字符串应该很简单。我以前一直在用硬编码为字符串长度的字节解析字符串,但是一旦我有一个长度为 128 的字符串失败,但这似乎有效:

typedef struct
{    
    ubyte stringLength;
    local int stringLengthLocal = stringLength;
    if(stringLength > 127)
    {
        stringLengthLocal = (ubyte)stringLength & (ubyte)127;
        ubyte stringLength2;
        stringLengthLocal += stringLength2 * 128;
    }

    char stringValue[stringLengthLocal] <optimize=false>;
} String;

【讨论】:

    【解决方案2】:

    我认为你需要一个能做两件事的函数:(1)提取内容长度; (2) 给你一个指向“真实”内容开始的地方。 看下面的代码,应该满足这两个要求:

    int getLength(const unsigned char *str, int *content_offset)
    {
        int result = 0, moreBytes=0, pos=0;
        do
        {
            unsigned char value7Bit = str[pos];
            result = (result << 7) | (value7Bit & 0x7F);
            moreBytes = value7Bit & 0x80;
            pos++;
        }
        while (moreBytes);
    
        if(content_offset)
            *content_offset = pos;
    
        return result;
    }
    
    
    int main() {
    
        unsigned char str[] = "\x81\x01teststring, which should contain 129 characters.....";
    
        int content_offset=0;
        int length = getLength(str, &content_offset);
    
        printf("length: %d; content: '%s'\n", length, str+content_offset);
        return 0;    
    }
    

    【讨论】:

    • 示例代码中的编码器看起来是 little-endian 的,尽管标签我认为它是用类似 C 语法的脚本语言实现的。
    猜你喜欢
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多