grizzly_ber 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/grizzly_ber.rb +130 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8b5a5500e1f13519b98923a3e30df1aa81775cbb
4
+ data.tar.gz: 8e5d9166d49e72973a2d0f5d6108dc811b2aff42
5
+ SHA512:
6
+ metadata.gz: bf4c45592fb3422f89d4546011b0c19612c2974431d43b301418be12e183c535f643c15faf08585e66dd0d601a8ef8b06e6eb86bd087272024727a037a89a021
7
+ data.tar.gz: 9d6d975a12bf2e322a2761d1049ee01b5d426436ad7ee0f3f93e063222aa4ac49df38ecaa0f697a99de24b79a5406483a9b73501eef74fb74abd947ebe46f865
@@ -0,0 +1,130 @@
1
+ class GrizzlyBer
2
+ attr_reader :value, :tag
3
+
4
+ def initialize(hex_string = "")
5
+ @tag = nil
6
+ @length = nil
7
+ @value = nil
8
+ decode_hex(hex_string)
9
+ end
10
+
11
+ def value=(new_value)
12
+ if new_value.is_a? String
13
+ @value = new_value
14
+ @tag = nil if isConstruct?
15
+ elsif new_value.is_a? Array and new_value.all? {|tlv| tlv.is_a? GrizzlyBer}
16
+ @value = new_value
17
+ @tag = nil if not isConstruct?
18
+ else
19
+ @value = nil
20
+ end
21
+ end
22
+
23
+ def tag=(new_tag)
24
+ @tag = new_tag
25
+ @value = nil if isConstruct? and @value.is_a? String
26
+ @value = nil if not isConstruct? and @value.is_a? Array
27
+ @value = [] if isConstruct? and @value.nil?
28
+ end
29
+
30
+ def decode_hex(hex_string)
31
+ decode_binary([hex_string].pack("H*"))
32
+ end
33
+
34
+ def decode_binary(binary_string)
35
+ decode_byte_array(binary_string.unpack("C*"))
36
+ end
37
+
38
+ def encode_hex
39
+ encoded = ""
40
+ encoded << @tag.to_s(16).upcase
41
+ if length_of_length == 1
42
+ encoded << length.to_s(16).rjust(2,'0').upcase
43
+ else
44
+ encoded << ((length_of_length-1) | 0x80).to_s(16).rjust(2,'0').upcase
45
+ encoded << length.to_s(16).rjust((length_of_length-1)*2,'0').upcase
46
+ end
47
+ encoded << encode_only_values
48
+ end
49
+
50
+ def encode_only_values
51
+ if @value.is_a? String
52
+ @value.upcase
53
+ else
54
+ @value.inject("") {|encoded_children,child| encoded_children << child.encode_hex}
55
+ end
56
+ end
57
+
58
+ protected
59
+
60
+ def length
61
+ return value.length/2 if value.is_a? String #because hex strings are 2 chars per byte
62
+ value.inject(0) {|length, tlv| length += tlv.length_of_tag + tlv.length_of_length + tlv.length}
63
+ end
64
+
65
+ def length_of_tag
66
+ [@tag.to_s(16)].pack("H*").unpack("C*").count
67
+ end
68
+
69
+ def length_of_length
70
+ 1 + ((length < 0x7F) ? 0 : [length.to_s(16)].pack("H*").unpack("C*").count)
71
+ end
72
+
73
+ def decode_byte_array(byte_array)
74
+ decode_value decode_length decode_tag byte_array
75
+ self
76
+ end
77
+
78
+ private
79
+
80
+ def decode_tag(byte_array)
81
+ byte_array.shift while byte_array.size > 0 and (byte_array[0] == 0x00 or byte_array[0] == 0xFF)
82
+ return [] if byte_array.size < 1
83
+
84
+ first_byte = byte_array.shift
85
+ @tag = first_byte
86
+ return byte_array if (first_byte & 0x1F) != 0x1F
87
+
88
+ while byte_array.size > 0
89
+ next_byte = byte_array.shift
90
+ @tag = (@tag << 8) | next_byte
91
+ return byte_array if (next_byte & 0x80) != 0x80
92
+ end
93
+
94
+ @tag = nil
95
+ []
96
+ end
97
+
98
+ def decode_length(byte_array)
99
+ return [] if byte_array.size < 1
100
+
101
+ first_byte = byte_array.shift
102
+ if (first_byte & 0x80) == 0x80
103
+ decoded_length_of_length = first_byte & 0x7F
104
+
105
+ return [] if byte_array.size < decoded_length_of_length
106
+ @length = 0
107
+ decoded_length_of_length.times { @length = (@length << 8) | byte_array.shift }
108
+ else
109
+ @length = first_byte
110
+ end
111
+
112
+ byte_array
113
+ end
114
+
115
+ def isConstruct?
116
+ ([@tag.to_s(16)].pack("H*").unpack("C*").first & 0x20) == 0x20
117
+ end
118
+
119
+ def decode_value(byte_array)
120
+ return [] if byte_array.size < 1 or byte_array.size < @length
121
+ if isConstruct?
122
+ @value = []
123
+ children_bytes = byte_array.shift(@length)
124
+ @value << GrizzlyBer.new.decode_byte_array(children_bytes) while children_bytes.size > 0
125
+ else
126
+ @value = byte_array.shift(@length).pack("C*").unpack("H*").first.upcase
127
+ end
128
+ end
129
+ end
130
+
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grizzly_ber
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Balsdon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: CODEC for TLV-BER encoded strings.
14
+ email: ryan.balsdon@shopify.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/grizzly_ber.rb
20
+ homepage: ''
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.2.2
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Fiercest TLV-BER parser
44
+ test_files: []