plum 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/Guardfile +7 -0
- data/LICENSE +21 -0
- data/README.md +14 -0
- data/Rakefile +12 -0
- data/bin/.gitkeep +0 -0
- data/examples/local_server.rb +206 -0
- data/examples/static_server.rb +157 -0
- data/lib/plum.rb +21 -0
- data/lib/plum/binary_string.rb +74 -0
- data/lib/plum/connection.rb +201 -0
- data/lib/plum/connection_utils.rb +38 -0
- data/lib/plum/errors.rb +35 -0
- data/lib/plum/event_emitter.rb +19 -0
- data/lib/plum/flow_control.rb +97 -0
- data/lib/plum/frame.rb +163 -0
- data/lib/plum/frame_factory.rb +53 -0
- data/lib/plum/frame_utils.rb +50 -0
- data/lib/plum/hpack/constants.rb +331 -0
- data/lib/plum/hpack/context.rb +55 -0
- data/lib/plum/hpack/decoder.rb +145 -0
- data/lib/plum/hpack/encoder.rb +105 -0
- data/lib/plum/hpack/huffman.rb +42 -0
- data/lib/plum/http_connection.rb +33 -0
- data/lib/plum/https_connection.rb +24 -0
- data/lib/plum/stream.rb +217 -0
- data/lib/plum/stream_utils.rb +58 -0
- data/lib/plum/version.rb +3 -0
- data/plum.gemspec +29 -0
- data/test/plum/connection/test_handle_frame.rb +70 -0
- data/test/plum/hpack/test_context.rb +63 -0
- data/test/plum/hpack/test_decoder.rb +291 -0
- data/test/plum/hpack/test_encoder.rb +49 -0
- data/test/plum/hpack/test_huffman.rb +36 -0
- data/test/plum/stream/test_handle_frame.rb +262 -0
- data/test/plum/test_binary_string.rb +64 -0
- data/test/plum/test_connection.rb +96 -0
- data/test/plum/test_connection_utils.rb +29 -0
- data/test/plum/test_error.rb +13 -0
- data/test/plum/test_flow_control.rb +167 -0
- data/test/plum/test_frame.rb +59 -0
- data/test/plum/test_frame_factory.rb +56 -0
- data/test/plum/test_frame_utils.rb +46 -0
- data/test/plum/test_https_connection.rb +37 -0
- data/test/plum/test_stream.rb +32 -0
- data/test/plum/test_stream_utils.rb +16 -0
- data/test/server.crt +19 -0
- data/test/server.csr +16 -0
- data/test/server.key +27 -0
- data/test/test_helper.rb +28 -0
- data/test/utils/assertions.rb +60 -0
- data/test/utils/server.rb +63 -0
- metadata +234 -0
data/lib/plum/frame.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
using Plum::BinaryString
|
2
|
+
|
3
|
+
module Plum
|
4
|
+
class Frame
|
5
|
+
extend FrameFactory
|
6
|
+
include FrameUtils
|
7
|
+
|
8
|
+
FRAME_TYPES = {
|
9
|
+
data: 0x00,
|
10
|
+
headers: 0x01,
|
11
|
+
priority: 0x02,
|
12
|
+
rst_stream: 0x03,
|
13
|
+
settings: 0x04,
|
14
|
+
push_promise: 0x05,
|
15
|
+
ping: 0x06,
|
16
|
+
goaway: 0x07,
|
17
|
+
window_update: 0x08,
|
18
|
+
continuation: 0x09
|
19
|
+
}
|
20
|
+
|
21
|
+
FRAME_FLAGS = {
|
22
|
+
data: {
|
23
|
+
end_stream: 0x01,
|
24
|
+
padded: 0x08
|
25
|
+
},
|
26
|
+
headers: {
|
27
|
+
end_stream: 0x01,
|
28
|
+
end_headers: 0x04,
|
29
|
+
padded: 0x08,
|
30
|
+
priority: 0x20
|
31
|
+
},
|
32
|
+
priority: {},
|
33
|
+
rst_stream: {},
|
34
|
+
settings: {
|
35
|
+
ack: 0x01
|
36
|
+
},
|
37
|
+
push_promise: {
|
38
|
+
end_headers: 0x04,
|
39
|
+
padded: 0x08
|
40
|
+
},
|
41
|
+
ping: {
|
42
|
+
ack: 0x01
|
43
|
+
},
|
44
|
+
goaway: {},
|
45
|
+
window_update: {},
|
46
|
+
continuation: {
|
47
|
+
end_headers: 0x04
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
SETTINGS_TYPE = {
|
52
|
+
header_table_size: 0x01,
|
53
|
+
enable_push: 0x02,
|
54
|
+
max_concurrent_streams: 0x03,
|
55
|
+
initial_window_size: 0x04,
|
56
|
+
max_frame_size: 0x05,
|
57
|
+
max_header_list_size: 0x06
|
58
|
+
}
|
59
|
+
|
60
|
+
# RFC7540: 4.1 Frame format
|
61
|
+
# +-----------------------------------------------+
|
62
|
+
# | Length (24) |
|
63
|
+
# +---------------+---------------+---------------+
|
64
|
+
# | Type (8) | Flags (8) |
|
65
|
+
# +-+-------------+---------------+-------------------------------+
|
66
|
+
# |R| Stream Identifier (31) |
|
67
|
+
# +=+=============================================================+
|
68
|
+
# | Frame Payload (0...) ...
|
69
|
+
# +---------------------------------------------------------------+
|
70
|
+
|
71
|
+
# [Integer] Frame type. 8-bit
|
72
|
+
attr_accessor :type_value
|
73
|
+
# [Integer] Flags. 8-bit
|
74
|
+
attr_accessor :flags_value
|
75
|
+
# [Integer] Stream Identifier. unsigned 31-bit integer
|
76
|
+
attr_accessor :stream_id
|
77
|
+
# [String] The payload.
|
78
|
+
attr_accessor :payload
|
79
|
+
|
80
|
+
def initialize(type: nil, type_value: nil, flags: nil, flags_value: nil, stream_id: nil, payload: nil)
|
81
|
+
self.payload = (payload || "")
|
82
|
+
self.type_value = type_value or self.type = type
|
83
|
+
self.flags_value = flags_value or self.flags = flags
|
84
|
+
self.stream_id = stream_id or raise ArgumentError.new("stream_id is necessary")
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the length of payload.
|
88
|
+
# @return [Integer] The length.
|
89
|
+
def length
|
90
|
+
@payload.bytesize
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the type of the frame in Symbol.
|
94
|
+
# @return [Symbol] The type.
|
95
|
+
def type
|
96
|
+
FRAME_TYPES.key(type_value) || ("unknown_%02x" % type_value).to_sym
|
97
|
+
end
|
98
|
+
|
99
|
+
# Sets the frame type.
|
100
|
+
# @param value [Symbol] The type.
|
101
|
+
def type=(value)
|
102
|
+
self.type_value = FRAME_TYPES[value] or raise ArgumentError.new("unknown frame type: #{value}")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the set flags on the frame.
|
106
|
+
# @return [Array<Symbol>] The flags.
|
107
|
+
def flags
|
108
|
+
fs = FRAME_FLAGS[type]
|
109
|
+
[0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]
|
110
|
+
.select {|v| flags_value & v > 0 }
|
111
|
+
.map {|val| fs && fs.key(val) || ("unknown_%02x" % val).to_sym }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Sets the frame flags.
|
115
|
+
# @param value [Array<Symbol>] The flags.
|
116
|
+
def flags=(value)
|
117
|
+
self.flags_value = (value && value.map {|flag| FRAME_FLAGS[self.type][flag] }.inject(:|) || 0)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Assembles the frame into binary representation.
|
121
|
+
# @return [String] Binary representation of this frame.
|
122
|
+
def assemble
|
123
|
+
bytes = "".force_encoding(Encoding::BINARY)
|
124
|
+
bytes.push_uint24(length)
|
125
|
+
bytes.push_uint8(type_value)
|
126
|
+
bytes.push_uint8(flags_value)
|
127
|
+
bytes.push_uint32(stream_id & ~(1 << 31)) # first bit is reserved (MUST be 0)
|
128
|
+
bytes.push(payload)
|
129
|
+
bytes
|
130
|
+
end
|
131
|
+
|
132
|
+
# @private
|
133
|
+
def inspect
|
134
|
+
"#<Plum::Frame:0x%04x} length=%d, type=%p, flags=%p, stream_id=0x%04x, payload=%p>" % [__id__, length, type, flags, stream_id, payload]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Parses a frame from given buffer. It changes given buffer.
|
138
|
+
#
|
139
|
+
# @param buffer [String] The buffer stored the data received from peer.
|
140
|
+
# @return [Frame, nil] The parsed frame or nil if the buffer is imcomplete.
|
141
|
+
def self.parse!(buffer)
|
142
|
+
buffer.force_encoding(Encoding::BINARY)
|
143
|
+
|
144
|
+
return nil if buffer.size < 9 # header: 9 bytes
|
145
|
+
length = buffer.uint24
|
146
|
+
return nil if buffer.size < 9 + length
|
147
|
+
|
148
|
+
bhead = buffer.byteshift(9)
|
149
|
+
payload = buffer.byteshift(length)
|
150
|
+
|
151
|
+
type_value = bhead.uint8(3)
|
152
|
+
flags_value = bhead.uint8(4)
|
153
|
+
r_sid = bhead.uint32(5)
|
154
|
+
r = r_sid >> 31
|
155
|
+
stream_id = r_sid & ~(1 << 31)
|
156
|
+
|
157
|
+
self.new(type_value: type_value,
|
158
|
+
flags_value: flags_value,
|
159
|
+
stream_id: stream_id,
|
160
|
+
payload: payload).freeze
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
using Plum::BinaryString
|
2
|
+
|
3
|
+
module Plum
|
4
|
+
module FrameFactory
|
5
|
+
def rst_stream(stream_id, error_type)
|
6
|
+
payload = "".push_uint32(HTTPError::ERROR_CODES[error_type])
|
7
|
+
Frame.new(type: :rst_stream, stream_id: stream_id, payload: payload)
|
8
|
+
end
|
9
|
+
|
10
|
+
def goaway(last_id, error_type, message = "")
|
11
|
+
payload = "".push_uint32((last_id || 0) | (0 << 31))
|
12
|
+
.push_uint32(HTTPError::ERROR_CODES[error_type])
|
13
|
+
.push(message)
|
14
|
+
Frame.new(type: :goaway, stream_id: 0, payload: payload)
|
15
|
+
end
|
16
|
+
|
17
|
+
def settings(ack = nil, **args)
|
18
|
+
payload = args.inject("") {|payload, (key, value)|
|
19
|
+
id = Frame::SETTINGS_TYPE[key] or raise ArgumentError.new("invalid settings type")
|
20
|
+
payload.push_uint16(id)
|
21
|
+
payload.push_uint32(value)
|
22
|
+
}
|
23
|
+
Frame.new(type: :settings, stream_id: 0, flags: [ack].compact, payload: payload)
|
24
|
+
end
|
25
|
+
|
26
|
+
def ping(arg1 = "plum\x00\x00\x00\x00", arg2 = nil)
|
27
|
+
if !arg2
|
28
|
+
raise ArgumentError.new("data must be 8 octets") if arg1.bytesize != 8
|
29
|
+
Frame.new(type: :ping, stream_id: 0, payload: arg1)
|
30
|
+
else
|
31
|
+
Frame.new(type: :ping, stream_id: 0, flags: [:ack], payload: arg2)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def data(stream_id, payload, *flags)
|
36
|
+
Frame.new(type: :data, stream_id: stream_id, flags: flags.compact, payload: payload.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def headers(stream_id, encoded, *flags)
|
40
|
+
Frame.new(type: :headers, stream_id: stream_id, flags: flags.compact, payload: encoded)
|
41
|
+
end
|
42
|
+
|
43
|
+
def push_promise(stream_id, new_id, encoded, *flags)
|
44
|
+
payload = "".push_uint32(0 << 31 | new_id)
|
45
|
+
.push(encoded)
|
46
|
+
Frame.new(type: :push_promise, stream_id: stream_id, flags: flags.compact, payload: payload)
|
47
|
+
end
|
48
|
+
|
49
|
+
def continuation(stream_id, payload, *flags)
|
50
|
+
Frame.new(type: :continuation, stream_id: stream_id, flags: flags.compact, payload: payload)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
using Plum::BinaryString
|
2
|
+
|
3
|
+
module Plum
|
4
|
+
module FrameUtils
|
5
|
+
# Splits the DATA frame into multiple frames if the payload size exceeds max size.
|
6
|
+
#
|
7
|
+
# @param max [Integer] The maximum size of a frame payload.
|
8
|
+
# @return [Array<Frame>] The splitted frames.
|
9
|
+
def split_data(max)
|
10
|
+
return [self] if self.length <= max
|
11
|
+
raise "Frame type must be DATA" unless self.type == :data
|
12
|
+
|
13
|
+
fragments = self.payload.each_byteslice(max).to_a
|
14
|
+
frames = fragments.map {|fragment| Frame.new(type: :data, flags: [], stream_id: self.stream_id, payload: fragment) }
|
15
|
+
frames.first.flags = self.flags - [:end_stream]
|
16
|
+
frames.last.flags = self.flags & [:end_stream]
|
17
|
+
frames
|
18
|
+
end
|
19
|
+
|
20
|
+
# Splits the HEADERS or PUSH_PROMISE frame into multiple frames if the payload size exceeds max size.
|
21
|
+
#
|
22
|
+
# @param max [Integer] The maximum size of a frame payload.
|
23
|
+
# @return [Array<Frame>] The splitted frames.
|
24
|
+
def split_headers(max)
|
25
|
+
return [self] if self.length <= max
|
26
|
+
raise "Frame type must be HEADERS or PUSH_PROMISE" unless [:headers, :push_promise].include?(self.type)
|
27
|
+
|
28
|
+
fragments = self.payload.each_byteslice(max).to_a
|
29
|
+
frames = fragments.map {|fragment| Frame.new(type: :continuation, flags: [], stream_id: self.stream_id, payload: fragment) }
|
30
|
+
frames.first.type_value = self.type_value
|
31
|
+
frames.first.flags = self.flags - [:end_headers]
|
32
|
+
frames.last.flags = self.flags & [:end_headers]
|
33
|
+
frames
|
34
|
+
end
|
35
|
+
|
36
|
+
# Parses SETTINGS frame payload. Ignores unknown settings type (see RFC7540 6.5.2).
|
37
|
+
#
|
38
|
+
# @return [Hash<Symbol, Integer>] The parsed strings.
|
39
|
+
def parse_settings
|
40
|
+
settings = {}
|
41
|
+
payload.each_byteslice(6) do |param|
|
42
|
+
id = param.uint16
|
43
|
+
name = Frame::SETTINGS_TYPE.key(id)
|
44
|
+
# ignore unknown settings type
|
45
|
+
settings[name] = param.uint32(2) if name
|
46
|
+
end
|
47
|
+
settings
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
module Plum
|
2
|
+
module HPACK
|
3
|
+
# RFC7541 Appendix A
|
4
|
+
# index is starting from 0
|
5
|
+
STATIC_TABLE = [
|
6
|
+
[":authority"],
|
7
|
+
[":method", "GET"],
|
8
|
+
[":method", "POST"],
|
9
|
+
[":path", "/"],
|
10
|
+
[":path", "/index.html"],
|
11
|
+
[":scheme", "http"],
|
12
|
+
[":scheme", "https"],
|
13
|
+
[":status", "200"],
|
14
|
+
[":status", "204"],
|
15
|
+
[":status", "206"],
|
16
|
+
[":status", "304"],
|
17
|
+
[":status", "400"],
|
18
|
+
[":status", "404"],
|
19
|
+
[":status", "500"],
|
20
|
+
["accept-charset"],
|
21
|
+
["accept-encoding", "gzip, deflate"],
|
22
|
+
["accept-language"],
|
23
|
+
["accept-ranges"],
|
24
|
+
["accept"],
|
25
|
+
["access-control-allow-origin"],
|
26
|
+
["age"],
|
27
|
+
["allow"],
|
28
|
+
["authorization"],
|
29
|
+
["cache-control"],
|
30
|
+
["content-disposition"],
|
31
|
+
["content-encoding"],
|
32
|
+
["content-language"],
|
33
|
+
["content-length"],
|
34
|
+
["content-location"],
|
35
|
+
["content-range"],
|
36
|
+
["content-type"],
|
37
|
+
["cookie"],
|
38
|
+
["date"],
|
39
|
+
["etag"],
|
40
|
+
["expect"],
|
41
|
+
["expires"],
|
42
|
+
["from"],
|
43
|
+
["host"],
|
44
|
+
["if-match"],
|
45
|
+
["if-modified-since"],
|
46
|
+
["if-none-match"],
|
47
|
+
["if-range"],
|
48
|
+
["if-unmodified-since"],
|
49
|
+
["last-modified"],
|
50
|
+
["link"],
|
51
|
+
["location"],
|
52
|
+
["max-forwards"],
|
53
|
+
["proxy-authenticate"],
|
54
|
+
["proxy-authorization"],
|
55
|
+
["range"],
|
56
|
+
["referer"],
|
57
|
+
["refresh"],
|
58
|
+
["retry-after"],
|
59
|
+
["server"],
|
60
|
+
["set-cookie"],
|
61
|
+
["strict-transport-security"],
|
62
|
+
["transfer-encoding"],
|
63
|
+
["user-agent"],
|
64
|
+
["vary"],
|
65
|
+
["via"],
|
66
|
+
["www-authenticate"],
|
67
|
+
]
|
68
|
+
|
69
|
+
HUFFMAN_TABLE = [
|
70
|
+
"1111111111000",
|
71
|
+
"11111111111111111011000",
|
72
|
+
"1111111111111111111111100010",
|
73
|
+
"1111111111111111111111100011",
|
74
|
+
"1111111111111111111111100100",
|
75
|
+
"1111111111111111111111100101",
|
76
|
+
"1111111111111111111111100110",
|
77
|
+
"1111111111111111111111100111",
|
78
|
+
"1111111111111111111111101000",
|
79
|
+
"111111111111111111101010",
|
80
|
+
"111111111111111111111111111100",
|
81
|
+
"1111111111111111111111101001",
|
82
|
+
"1111111111111111111111101010",
|
83
|
+
"111111111111111111111111111101",
|
84
|
+
"1111111111111111111111101011",
|
85
|
+
"1111111111111111111111101100",
|
86
|
+
"1111111111111111111111101101",
|
87
|
+
"1111111111111111111111101110",
|
88
|
+
"1111111111111111111111101111",
|
89
|
+
"1111111111111111111111110000",
|
90
|
+
"1111111111111111111111110001",
|
91
|
+
"1111111111111111111111110010",
|
92
|
+
"111111111111111111111111111110",
|
93
|
+
"1111111111111111111111110011",
|
94
|
+
"1111111111111111111111110100",
|
95
|
+
"1111111111111111111111110101",
|
96
|
+
"1111111111111111111111110110",
|
97
|
+
"1111111111111111111111110111",
|
98
|
+
"1111111111111111111111111000",
|
99
|
+
"1111111111111111111111111001",
|
100
|
+
"1111111111111111111111111010",
|
101
|
+
"1111111111111111111111111011",
|
102
|
+
"010100",
|
103
|
+
"1111111000",
|
104
|
+
"1111111001",
|
105
|
+
"111111111010",
|
106
|
+
"1111111111001",
|
107
|
+
"010101",
|
108
|
+
"11111000",
|
109
|
+
"11111111010",
|
110
|
+
"1111111010",
|
111
|
+
"1111111011",
|
112
|
+
"11111001",
|
113
|
+
"11111111011",
|
114
|
+
"11111010",
|
115
|
+
"010110",
|
116
|
+
"010111",
|
117
|
+
"011000",
|
118
|
+
"00000",
|
119
|
+
"00001",
|
120
|
+
"00010",
|
121
|
+
"011001",
|
122
|
+
"011010",
|
123
|
+
"011011",
|
124
|
+
"011100",
|
125
|
+
"011101",
|
126
|
+
"011110",
|
127
|
+
"011111",
|
128
|
+
"1011100",
|
129
|
+
"11111011",
|
130
|
+
"111111111111100",
|
131
|
+
"100000",
|
132
|
+
"111111111011",
|
133
|
+
"1111111100",
|
134
|
+
"1111111111010",
|
135
|
+
"100001",
|
136
|
+
"1011101",
|
137
|
+
"1011110",
|
138
|
+
"1011111",
|
139
|
+
"1100000",
|
140
|
+
"1100001",
|
141
|
+
"1100010",
|
142
|
+
"1100011",
|
143
|
+
"1100100",
|
144
|
+
"1100101",
|
145
|
+
"1100110",
|
146
|
+
"1100111",
|
147
|
+
"1101000",
|
148
|
+
"1101001",
|
149
|
+
"1101010",
|
150
|
+
"1101011",
|
151
|
+
"1101100",
|
152
|
+
"1101101",
|
153
|
+
"1101110",
|
154
|
+
"1101111",
|
155
|
+
"1110000",
|
156
|
+
"1110001",
|
157
|
+
"1110010",
|
158
|
+
"11111100",
|
159
|
+
"1110011",
|
160
|
+
"11111101",
|
161
|
+
"1111111111011",
|
162
|
+
"1111111111111110000",
|
163
|
+
"1111111111100",
|
164
|
+
"11111111111100",
|
165
|
+
"100010",
|
166
|
+
"111111111111101",
|
167
|
+
"00011",
|
168
|
+
"100011",
|
169
|
+
"00100",
|
170
|
+
"100100",
|
171
|
+
"00101",
|
172
|
+
"100101",
|
173
|
+
"100110",
|
174
|
+
"100111",
|
175
|
+
"00110",
|
176
|
+
"1110100",
|
177
|
+
"1110101",
|
178
|
+
"101000",
|
179
|
+
"101001",
|
180
|
+
"101010",
|
181
|
+
"00111",
|
182
|
+
"101011",
|
183
|
+
"1110110",
|
184
|
+
"101100",
|
185
|
+
"01000",
|
186
|
+
"01001",
|
187
|
+
"101101",
|
188
|
+
"1110111",
|
189
|
+
"1111000",
|
190
|
+
"1111001",
|
191
|
+
"1111010",
|
192
|
+
"1111011",
|
193
|
+
"111111111111110",
|
194
|
+
"11111111100",
|
195
|
+
"11111111111101",
|
196
|
+
"1111111111101",
|
197
|
+
"1111111111111111111111111100",
|
198
|
+
"11111111111111100110",
|
199
|
+
"1111111111111111010010",
|
200
|
+
"11111111111111100111",
|
201
|
+
"11111111111111101000",
|
202
|
+
"1111111111111111010011",
|
203
|
+
"1111111111111111010100",
|
204
|
+
"1111111111111111010101",
|
205
|
+
"11111111111111111011001",
|
206
|
+
"1111111111111111010110",
|
207
|
+
"11111111111111111011010",
|
208
|
+
"11111111111111111011011",
|
209
|
+
"11111111111111111011100",
|
210
|
+
"11111111111111111011101",
|
211
|
+
"11111111111111111011110",
|
212
|
+
"111111111111111111101011",
|
213
|
+
"11111111111111111011111",
|
214
|
+
"111111111111111111101100",
|
215
|
+
"111111111111111111101101",
|
216
|
+
"1111111111111111010111",
|
217
|
+
"11111111111111111100000",
|
218
|
+
"111111111111111111101110",
|
219
|
+
"11111111111111111100001",
|
220
|
+
"11111111111111111100010",
|
221
|
+
"11111111111111111100011",
|
222
|
+
"11111111111111111100100",
|
223
|
+
"111111111111111011100",
|
224
|
+
"1111111111111111011000",
|
225
|
+
"11111111111111111100101",
|
226
|
+
"1111111111111111011001",
|
227
|
+
"11111111111111111100110",
|
228
|
+
"11111111111111111100111",
|
229
|
+
"111111111111111111101111",
|
230
|
+
"1111111111111111011010",
|
231
|
+
"111111111111111011101",
|
232
|
+
"11111111111111101001",
|
233
|
+
"1111111111111111011011",
|
234
|
+
"1111111111111111011100",
|
235
|
+
"11111111111111111101000",
|
236
|
+
"11111111111111111101001",
|
237
|
+
"111111111111111011110",
|
238
|
+
"11111111111111111101010",
|
239
|
+
"1111111111111111011101",
|
240
|
+
"1111111111111111011110",
|
241
|
+
"111111111111111111110000",
|
242
|
+
"111111111111111011111",
|
243
|
+
"1111111111111111011111",
|
244
|
+
"11111111111111111101011",
|
245
|
+
"11111111111111111101100",
|
246
|
+
"111111111111111100000",
|
247
|
+
"111111111111111100001",
|
248
|
+
"1111111111111111100000",
|
249
|
+
"111111111111111100010",
|
250
|
+
"11111111111111111101101",
|
251
|
+
"1111111111111111100001",
|
252
|
+
"11111111111111111101110",
|
253
|
+
"11111111111111111101111",
|
254
|
+
"11111111111111101010",
|
255
|
+
"1111111111111111100010",
|
256
|
+
"1111111111111111100011",
|
257
|
+
"1111111111111111100100",
|
258
|
+
"11111111111111111110000",
|
259
|
+
"1111111111111111100101",
|
260
|
+
"1111111111111111100110",
|
261
|
+
"11111111111111111110001",
|
262
|
+
"11111111111111111111100000",
|
263
|
+
"11111111111111111111100001",
|
264
|
+
"11111111111111101011",
|
265
|
+
"1111111111111110001",
|
266
|
+
"1111111111111111100111",
|
267
|
+
"11111111111111111110010",
|
268
|
+
"1111111111111111101000",
|
269
|
+
"1111111111111111111101100",
|
270
|
+
"11111111111111111111100010",
|
271
|
+
"11111111111111111111100011",
|
272
|
+
"11111111111111111111100100",
|
273
|
+
"111111111111111111111011110",
|
274
|
+
"111111111111111111111011111",
|
275
|
+
"11111111111111111111100101",
|
276
|
+
"111111111111111111110001",
|
277
|
+
"1111111111111111111101101",
|
278
|
+
"1111111111111110010",
|
279
|
+
"111111111111111100011",
|
280
|
+
"11111111111111111111100110",
|
281
|
+
"111111111111111111111100000",
|
282
|
+
"111111111111111111111100001",
|
283
|
+
"11111111111111111111100111",
|
284
|
+
"111111111111111111111100010",
|
285
|
+
"111111111111111111110010",
|
286
|
+
"111111111111111100100",
|
287
|
+
"111111111111111100101",
|
288
|
+
"11111111111111111111101000",
|
289
|
+
"11111111111111111111101001",
|
290
|
+
"1111111111111111111111111101",
|
291
|
+
"111111111111111111111100011",
|
292
|
+
"111111111111111111111100100",
|
293
|
+
"111111111111111111111100101",
|
294
|
+
"11111111111111101100",
|
295
|
+
"111111111111111111110011",
|
296
|
+
"11111111111111101101",
|
297
|
+
"111111111111111100110",
|
298
|
+
"1111111111111111101001",
|
299
|
+
"111111111111111100111",
|
300
|
+
"111111111111111101000",
|
301
|
+
"11111111111111111110011",
|
302
|
+
"1111111111111111101010",
|
303
|
+
"1111111111111111101011",
|
304
|
+
"1111111111111111111101110",
|
305
|
+
"1111111111111111111101111",
|
306
|
+
"111111111111111111110100",
|
307
|
+
"111111111111111111110101",
|
308
|
+
"11111111111111111111101010",
|
309
|
+
"11111111111111111110100",
|
310
|
+
"11111111111111111111101011",
|
311
|
+
"111111111111111111111100110",
|
312
|
+
"11111111111111111111101100",
|
313
|
+
"11111111111111111111101101",
|
314
|
+
"111111111111111111111100111",
|
315
|
+
"111111111111111111111101000",
|
316
|
+
"111111111111111111111101001",
|
317
|
+
"111111111111111111111101010",
|
318
|
+
"111111111111111111111101011",
|
319
|
+
"1111111111111111111111111110",
|
320
|
+
"111111111111111111111101100",
|
321
|
+
"111111111111111111111101101",
|
322
|
+
"111111111111111111111101110",
|
323
|
+
"111111111111111111111101111",
|
324
|
+
"111111111111111111111110000",
|
325
|
+
"11111111111111111111101110",
|
326
|
+
"111111111111111111111111111111"
|
327
|
+
]
|
328
|
+
|
329
|
+
HUFFMAN_TABLE_INVERSED = HUFFMAN_TABLE.each_with_index.to_h
|
330
|
+
end
|
331
|
+
end
|