2011-08-03 35 views
2

最近我絆倒在Ruby中的代碼片段:紅寶石陌生的字符串使用與Integer.chr和 「 001」

@data = 3.chr * 5 

導致 「\ 003 \ 003 \ 003 \ 003 \ 003」

在後面的代碼例如

flag = @data[2] & 2 

時, 我知道它有什麼用待辦事項按位標誌。看起來值1,2和3被用作狀態標誌,但因爲ruby 1.9,這是我熟悉的版本,改變了Integer.chr方法,代碼不再工作,我真的很想知道最新的情況上。 此外,「\ 00x」逃脫事件的目的是什麼?

謝謝您的回答

回答

4

要在Ruby 1.9的代碼工作,請嘗試更改該行:

flag = @data[2].ord & 2 

此前的Ruby 1.9,str[n]將返回0和255之間的整數,但在Ruby 1.9中支持新的Unicode,str[n]返回一個字符(長度爲1的字符串)。要獲得整數而不是字符,可以在字符上調用.ord

&運算符只是C,Ruby和其他許多語言的標準按位運算符。

字節編號三(0x03)不是可打印的ASCII字符,所以當你在字符串中有該字節並且調用inspect ruby​​表示該字節爲\003。只要確保你明白「\ 003」是一個單字節字符串,而'\ 003'是一個四字節字符串。

在Ruby中,字符串實際上是字節序列。在Ruby 1.9中,也有編碼信息,但它們仍然只是一個字節序列。

+0

感謝您的回答,正是我想要的:) – Markus1189

1

「\ 00X」是一個值的八進制表示。

所以,如果我們這樣做:

irb(main):001:0> 15.chr 
=> "\017" 
irb(main):002:0> 16.chr 
=> "\020" 

通知我們,從17如何直接去20?八。

「\ 003 \ 003 \ 003 \ 003 \ 003」是值爲3的5個字節,然後您可以按位與他們與其他字節,如2或\ 002。

SO 3或0011二進制與2(0010)是相與2(0010)

1.9問題發生在帳戶的1.9不使用ASCII像1.8一樣。大衛格雷森好點。

+0

thx爲與八進制的筆記,很高興知道但不完全是我的意圖 – Markus1189

1

請注意,紅寶石1。9將在十六進制表示檢查不可打印的字符:

3.chr # => "\x03" 

更令人困惑的是,有時串會出現在的Unicode(UTF-8):

"\003" # => "\u0003" (utf-8) 
3.chr.encoding # => #<Encoding:US-ASCII> 
"\003".encoding # => #<Encoding:UTF-8> 
"\003" == 3.chr # => true (this is strange because the encoding is different) 

如果你想了解如何這些八進制和六角串涉及十進制數,可以將它們轉換成二進制:

"\003".unpack('B*') # same as "\003".ord.to_s(2) 
# => ["00000011"] # the 2 least significant bits are set 
2.to_s(2) # convert to base 2 
#=> "10" 

表達3 & 2是位與二進制編號爲11b和10b,這將產生10b(因爲對於最高有效位,1是1; 1 & 0對於最不重要的)。

其他轉換:

'%x' % 97 # => '61' hex 
0x61 # => 97 decimal from raw hex input 
'%o' % 97 # => '141' octal 
0141 # => 97 decimal from raw octal input 

這有點臨陣磨槍,但你或許應該谷歌更深入的信息。

+0

thx爲那真的很好的解釋,通過按位運算符不是未知數。 – Markus1189