代码之家  ›  专栏  ›  技术社区  ›  HarlemSquirrel

如何使用ruby解码这个edid字符串?

  •  1
  • HarlemSquirrel  · 技术社区  · 7 年前

    我有一个文件。它似乎是二进制字符集。

    $ file -bi /sys/devices/pci0000:00/0000:00:03.1/0000:0b:00.0/drm/card0/card0-DP-1/edid
    inode/x-empty; charset=binary
    

    打电话没用 File.read

    filepath = '/sys/devices/pci0000:00/0000:00:03.1/0000:0b:00.0/drm/card0/card0-DP-1/edid'
    File.read(filepath)
    # => "\u0000\xFF\xFF\xFF\xFF\xFF\xFF\u0000\u0004i\xA3'e\f\u0000\u0000\u0006\u0018\u0001\u0004\xA5<\"x:\xA5\x95\xAATO\xA1&\nPT\xB7\xEF\u0000\xD1\xC0\xB3\u0000\x95\u0000\x81\x80\x81@\x81\u0000\x81\xC0qOV^\u0000\xA0\xA0\xA0)P0 5\u0000UP!\u0000\u0000\u001A\u0000\u0000\u0000\xFF\u0000E2LMTF003173\n\u0000\u0000\u0000\xFD\u0000\u0018L\u0018c\u001E\u0004\u0011\u0001@\xF88\xF0<\u0000\u0000\u0000\xFC\u0000ASUS PB278\n  \u0001\xF2\u0002\u0003\"qO\u0001\u0002\u0003\u0011\u0012\u0013\u0004\u0014\u0005\u001F\x90\u000E\u000F\u001D\u001E#\t\u0017\a\x83\u0001\u0000\u0000en\f\u0000\u0010\u0000\x8C\nЊ \xE0-\u0010\u0010>\x96\u0000UP!\u0000\u0000\u0018\u0001\u001D\u0000rQ\xD0\u001E n(U\u0000UP!\u0000\u0000\u001E\u0001\u001D\u0000\xBCR\xD0\u001E \xB8(U@UP!\u0000\u0000\u001E\x8C\nА @1 \f@U\u0000UP!\u0000\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\x96"
    

    把它读成二进制是没有帮助的

    File.open(filepath, 'rb').read
    # => "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x04i\xA3'e\f\x00\x00\x06\x18\x01\x04\xA5<\"x:\xA5\x95\xAATO\xA1&\nPT\xB7\xEF\x00\xD1\xC0\xB3\x00\x95\x00\x81\x80\x81@\x81\x00\x81\xC0qOV^\x00\xA0\xA0\xA0)P0 5\x00UP!\x00\x00\x1A\x00\x00\x00\xFF\x00E2LMTF003173\n\x00\x00\x00\xFD\x00\x18L\x18c\x1E\x04\x11\x01@\xF88\xF0<\x00\x00\x00\xFC\x00ASUS PB278\n  \x01\xF2\x02\x03\"qO\x01\x02\x03\x11\x12\x13\x04\x14\x05\x1F\x90\x0E\x0F\x1D\x1E#\t\x17\a\x83\x01\x00\x00en\f\x00\x10\x00\x8C\n\xD0\x8A \xE0-\x10\x10>\x96\x00UP!\x00\x00\x18\x01\x1D\x00rQ\xD0\x1E n(U\x00UP!\x00\x00\x1E\x01\x1D\x00\xBCR\xD0\x1E \xB8(U@UP!\x00\x00\x1E\x8C\n\xD0\x90 @1 \f@U\x00UP!\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96"
    
    puts File.open(filepath, 'rb').read
    

    输出:

    ������i�'e
              �<"x:���TO�&
    PT���������@���qOV^���)P0 5UP!��E2LMTF003173
    �Lc@�8�<�ASUS PB278
      �"qO�#    �en
                       �
    Њ �->�UP!rQ� n(UUP!�R� �(U@UP!�
    А @1 
         @UUP!�
    

    我也试过这个

    puts File.open(filepath, "r:ISO-8859-1:UTF-8", &:read)
    

    输出:

    ÿÿÿÿÿÿi£'e
              ¥<"x:¥ªTO¡&
    PT·ïÑÀ³@ÀqOV^   )P0 5UP!�ÿE2LMTF003173
    ýLc@ø8ð<üASUS PB278
      ò"qOen
    
    Ð à->UP!rQÐ n(UUP!¼RÐ ¸(U@UP!
    Ð
    

    rchardet 也没有帮助。

    CharDet.detect File.open(filepath, 'rb').read
    # => {"encoding"=>nil, "confidence"=>0.0}
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Kimmo Lehto    7 年前

    由于edid是一种二进制格式,并且似乎没有可用于解析它的gem,因此我建议使用 bindata gem创建数据模型,如 EDID 维基百科页面。

    对于前两个字段,它类似于:

    require 'bindata'
    
    module EDID
      class Record < BinData::Record
        HEADER_BYTES = [0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00]
        array :header_bytes, type: :uint8, initial_length: 8, value: HEADER_BYTES, assert_value: HEADER_BYTES
        bit1 :manufacturer_id_pad, value: 0
        array :manufacturer_id, type: :bit5, initial_length: 3
        uint16le :product_code
        uint32le :serial_number
        uint8 :manufacture_week
        uint8 :manufacture_year
        uint8 :edid_version, initial_value: 1
        uint8 :edid_revision, initial_value: 3
    
        def manufacturer
          manufacturer_id.map { |int| (int+64).chr }.join
        end
    
        def manufacture_year_real
          manufacture_week == 255 ? manufacture_year : (manufacture_year + 1990)
        end
    
        def to_s
          <<~EOB
            Manufacturer: #{manufacturer}
            Product: #{product_code}
            Serial: #{serial_number}
            Manufacture_year: #{manufacture_year_real}
            Manufacture_week: #{manufacture_week == 255 ? 'unknown' : manufacture_week}
          EOB
        end
      end
    end
    

    并将其与您的数据一起使用:

    io = File.open('/sys/devices/pci0000:00/0000:00:03.1/0000:0b:00.0/drm/card0/card0-DP-1/edid')
    record = EDID::Record.read(io)
    puts record
    

    输出:

    Manufacturer: ACI
    Product: 10147
    Serial: 3173
    Manufacture_year: 2014
    Manufacture_week: 6
    
    推荐文章