【问题标题】:Do you understand what this code is aiming to do?你明白这段代码的目的是什么吗?
【发布时间】:2019-08-09 14:47:54
【问题描述】:

我从不在这里写信,但和几乎每个人一样,我经常阅读问题和答案……现在是我提问的时候了:)

所以,我正在阅读一段很长的代码,该代码适用于字节流以解码电子护照的标签和值(ICAO Doc 9303 定义了国际技术规范)......直到我找到这部分内容并不难(我在神秘部分前后放置了cmets)

int len = s.read(); // s is an InputStream    
readPos++;
if ((len > 0x80)) {
    int lenlen = len - 0x80;
    len = 0;
    for (int i = 0; (i < lenlen); i++) {
        if ((readPos == length)) {
            throw new ParseException();
        }
        // wtf begin
        len = (len << 8) | ((byte) (s.read()));
        // wtf end
        readPos++;
    }
}
size = readPos + len;

我知道它从 InputStream 中逐字节读取,并增加字节流中的位置,但为什么它执行移位并将结果保存在变量 len 中?如果我没记错的话,len 会被一遍又一遍地覆盖,那么这个变量在 for 循环之后怎么会有有意义的值呢?

【问题讨论】:

  • 它正在逐字节读取 len 变量。最高有效字节首先出现。比你乘以 8(字节大小)并添加下一个字节(这里用按位或写)。想想逐位读取一个数字。

标签: java parsing


【解决方案1】:

它正在处理lenlen 字节数,并从这些字节中生成一个大端序数:

  • 大小写长度为

    if不输入,len代表单字节数

  • case len == 128+1, +2, +3, +4

    分别使用1、2、3、4个字节:每个字节至少放置 重要位置以及较旧的字节向左移动一个字节位置(&lt;&lt; 8)。所以 129 表示 1 字节长度(对于 128 到 255 之间的数字), 2 字节数为 130。

  • 最后:len 字节被跳过。

数据完整性需要检查原始 len >= 0、len len 是否也 >= 0。


编写过程你可能遇到的逆算法:

if (len <= 128) {
    out.write((byte)len);
} else {
    int bytes = 4 - Integer.numberOfLeadingZeroes(len) / 8;
    out.write(128 + bytes);
    for (int i = 0; i < bytes; ++i) {
        int b = len >>>(bytes - 1);
        out.write((byte)b); // Truncates the int to just 1 byte.
    }
}

(假设len 是正数。)

【讨论】:

  • 乔普,伙计,你真棒。您的示例也有助于理解核心概念。
猜你喜欢
  • 2020-03-02
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2014-04-11
  • 1970-01-01
  • 2010-12-14
相关资源
最近更新 更多