2013-06-18 6 views
0

У меня есть два тестовых примера, где вызывается метод data_valid?. Первый возвращает false, а второй возвращает true, почему?Почему символы, отличные от ASCII, не равны?

55: def data_valid? d 
    56: crc = d[-1] 
    57: data = d[1..-2] 
    58: len = d[0] 
=> 59: binding.pry 
    60: (data^len) == crc 
    61: end 

2.0.0 (#<MicroAeth::Message:0x007fbefc3ceae8>):0 > (data^len) == crc 
=> false 
2.0.0 (#<MicroAeth::Message:0x007fbefc3ceae8>):0 > (data^len) 
=> "\xB1" 
2.0.0 (#<MicroAeth::Message:0x007fbefc3ceae8>):0 > crc 
=> "\xB1" 
2.0.0 (#<MicroAeth::Message:0x007fbefc3ceae8>):0 > exit 
have a good day! 
F 
From: /Users/rudolph9/Projects/CombustionEmissionsTesting/micro_aeth.rb @ line 59 MicroAeth::Message#data_valid?: 

    55: def data_valid? d 
    56: crc = d[-1] 
    57: data = d[1..-2] 
    58: len = d[0] 
=> 59: binding.pry 
    60: (data^len) == crc 
    61: end 

2.0.0 (#<MicroAeth::Message:0x007fbefe83a8c8>):0 > (data^len) == crc 
=> true 
2.0.0 (#<MicroAeth::Message:0x007fbefe83a8c8>):0 > (data^len) 
=> "+" 
2.0.0 (#<MicroAeth::Message:0x007fbefe83a8c8>):0 > crc 
=> "+" 

Ниже мое расширение класса строки, в которой я сравниваю возвращение пользовательского метода XOR ^.

class ::String 
    ### 
    # @return the first charater in the string as an integer 
    def byte 
     self.bytes[0] 
    end 

    ### 
    # XOR two strings 
    # @str assumed to be a one byte string or integer 
    def^str 
     if str.class == String 
     str = str.byte 
     elsif str.class == Fixnum 
     nil 
     else 
     raise "invalid arg: #{str.class} \n Must be String or Fixnum" 
     end 
     self.bytes.each do |i| 
     str = str^i 
     end 
     str.chr 
    end 
    end 

Я считаю, что это как-то связано с первым сопоставлением символов, отличных от ASCII. Как правильно настроить условное выражение?

+1

Какие кодировки строк? Вызовите [#encoding] (http://www.ruby-doc.org/core-2.0/String.html#method-i-encoding) для проверки. –

+0

@XiongChiamiov '2.0.0 (# ): 0> crc.encoding => # <Кодирование: UTF-8> 2.0.0 (# ) : 0> (data^len) .encoding => # <Кодирование: ASCII-8BIT> ' – rudolph9

+0

У меня возникли проблемы с преобразованием строк в целях сравнения:' 2.0.0 (# ) : 0> (data^len) .encode crc.encoding Кодирование :: UndefinedConversionError: "\ xB1" из ASCII-8BIT в UTF-8 из (pry): 12: в 'encode ' 2.0.0 (# < MicroAeth :: Message: 0x007f8e642eec18>): 0> crc.encode (data^len) .encoding Кодировка :: InvalidByteSequenceError: "\ xB1" в UTF-8 от (pry): 13: в 'encode'' как сделать Я подхожу к общему кодированию? – rudolph9

ответ

1

Вы можете использовать String#force_encoding, чтобы заставить строку в указанную кодировку

2.0.0-p195 :001 > "\xB1".encoding 
=> #<Encoding:UTF-8> 
2.0.0-p195 :002 > eight_bit = "\xB1".force_encoding(Encoding::ASCII_8BIT) 
=> "\xB1" 
2.0.0-p195 :003 > eight_bit.encoding 
=> #<Encoding:ASCII-8BIT> 
2.0.0-p195 :004 > eight_bit == "\xB1" 
=> false 
2.0.0-p195 :005 > eight_bit.force_encoding(Encoding::UTF_8) == "\xB1" 
=> true 
2.0.0-p195 :006 > eight_bit.force_encoding("\xB1".encoding) == "\xB1" 
=> true 

Примечание кодировкой по умолчанию для Ruby, 2.0.0 является UTF-8

Смежные вопросы