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

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

@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 是什么意思啊?

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 中...

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