此字节顺序转换是否正确?

时间:2014-12-19 17:13:19

标签: php endianness modbus

我正在阅读一个库(github.com/adduc/phpmodbus),这个函数用于将整数转换为little-endian或big-endian字节串:

private static function endianness($value, $endianness = 0) {
    if ($endianness == 0)
        return
                self::iecBYTE(($value >> 8) & 0x000000FF) .
                self::iecBYTE(($value & 0x000000FF)) .
                self::iecBYTE(($value >> 24) & 0x000000FF) .
                self::iecBYTE(($value >> 16) & 0x000000FF);
    else
        return
                self::iecBYTE(($value >> 24) & 0x000000FF) .
                self::iecBYTE(($value >> 16) & 0x000000FF) .
                self::iecBYTE(($value >> 8) & 0x000000FF) .
                self::iecBYTE(($value & 0x000000FF));
}

iecBYTE功能只是chr($value & 0xFF)

现在也许我很厚,但是小端字符串看起来不对 例如,使用0xAABBCCDD,您将获得{CC}{DD}{AA}{BB}

我甚至在维基百科上查了一下。不应该是{DD}{CC}{BB}{AA}

代码有效,这让我很困惑。是不是我理解错了?

2 个答案:

答案 0 :(得分:0)

你是对的。功能不对,虽然它很接近。看起来你只需交换一些转换。逻辑上,little-endian转换($ endianness == 0)只是big-endian转换的反转($ endianness!= 0)。

private static function endianness($value, $endianness = 0) {
    if ($endianness == 0) //little-endian
        return
                self::iecBYTE($value & 0x000000FF) .
                self::iecBYTE(($value >> 8) & 0x000000FF) .
                self::iecBYTE(($value >> 16) & 0x000000FF) .
                self::iecBYTE(($value >> 24) & 0x000000FF);
    else //big-endian
        return
                self::iecBYTE(($value >> 24) & 0x000000FF) .
                self::iecBYTE(($value >> 16) & 0x000000FF) .
                self::iecBYTE(($value >> 8) & 0x000000FF) .
                self::iecBYTE(($value & 0x000000FF));
}

答案 1 :(得分:0)

在查看IECType.php之后,我注意到它正在将PHP类型转换为IEC 1131类型。 小端首先存储最不重要的字节。你的描述会让我觉得系统使用的是16位地址。

如果您查看endianess函数上方注释中引用的Endianess的wiki,那么您将在Little-endian下看到一个名为Atomic element size 16-bit的部分。一个地址包含两个字节(CCDD)和(AABB)。持有(CCDD)的地址最不重要,因此它将首先列出。

如果你在8位系统中工作,那么每个字节都会被排序(DDCCBBAA),因为每个地址会有一个字节。

Wiki描述了您在endianess函数中看到的内容。

address1| address2
16-bits | 16-bits
 CCDD   |  AABB