Gem 请教 @luikore String.unpack 中的 "S>" 是什么意思?

wppurking · 2013年06月24日 · 最后由 wppurking 回复于 2013年06月24日 · 3508 次阅读

@luikore 因为在学习 EventMachine 所以在看你这个项目 "stochastic-socks"

现在还在看 local.rb - -|| 请问一下, 根据 rfc1928 解析出来的最后两位 BND.PORT 用 String.unpack("S>") 解析出具体端口值, 这个带 >S> 是什么意思呢?

还有就是请教一下 S | Integer | 16-bit unsigned, native endian (unit16_t) 这里的 N-bit unsigned/signed 是什么意思啊?

共收到 4 条回复

unpack 文档如 #1楼 链接

bit 就是位, 8 bit 等于 1 字节

S 意思是 short, 在 C 语言里 short 是 16 位也就是两字节表示的整数 小写 s 是有符号(signed, 也就是能加负号), 能表示的整数范围是 -32768 到 32767 大写 S 是无符号(unsigned, 也就是不能加负号), 能表示的整数范围是 0 到 65535 (所以 socket 端口可以在 0..65535 取值)


关于 endian

假设有两个字节 \x01\x02, 可以解释成 1*256 + 2, 也可以解释成 1 + 2*256, 到底怎么解释要看系统或者协议是怎么规定的. native endian 就是使用和系统一致的 endian.

网络协议中一般用 big endian (network endian 和 big endian 一个意思).

big endian 的意思就是先接收到的字节表示高位, 后接收到的字节表示低位. unpack 中用 > 表示 big endian, < 表示 little endian. 之所以用 > 这个符号是因为比较形象: 左边的字节对结果影响比较大.

"\x01\x00".unpack 'S>' #=> 1 * 256 + 0 = 256
"\x00\x01".unpack 'S>' #=> 0 * 256 + 1 = 1

#1楼 @leozwa S>S 可以一样也可以不一样, 由于 S 用的是 native endian, 系统是 big endian 才一样.

在 VAX, x86 指令里用的 word/dword/qword 数据, 处理字符串的 W 系列的 win32 API 里, 用的是 little endian. 我们的台机和本基本是 x86 的, 所以 native endian 往往等于 little endian. Mac OS X 的 NSString 内部也是用 little endian 的 utf-16 code unit.

但以前 sun 为了让 java 在他们的 sparc 上跑得比较快 (sparc 是 big endian 的), 字符串用了 big endian 的 utf-16 做内部表示(文档里就笼统的说 unicode, 反正也没暴露 API).

@leozwa @luikore 首先得说, 大家果然晚上效率高啊! 我弄完 google, doc 了半天卡在着提了问题准备白天看答案的, 发现大家都是 3,4 点留言 - -||

@leozwa 我也是看着文档中写着 same as the directives without ">" except 同时碰到测试的结果却不一样, 所以就迷糊了, 而且文档中找来找去也只是给了 *, _ 这些符号的解释. 例如

a = "\x01\xBB"
a.unpack "S"  # [47873]
a.unpack "S>"  #[443]

正在结合 @luikore 的讲解理解 signed_numbers 中...

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册