hex_string 1.0.0

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.
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ doc
5
+ .yardoc
@@ -0,0 +1 @@
1
+ --markup markdown --readme README.md --hide-void-return
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hex_string.gemspec
4
+ gemspec
@@ -0,0 +1,46 @@
1
+ Description
2
+ ===========
3
+ HexString provides two String extension methods:
4
+
5
+ * `String#to_hex_string` explodes a string of binary data into human-readable hex tuples, and
6
+ * `String#to_byte_string` converts a string of human-readable hex digits into the corresponding bytes.
7
+
8
+ Examples
9
+ --------
10
+
11
+ # Convert data to human-readable hex tuples:
12
+ >> "hello".to_hex_string
13
+ => "68 65 6c 6c 6f"
14
+
15
+ # Compact a hex string into its data equivalent:
16
+ >> "77 6f 72 6c 64".to_byte_string
17
+ => "world"
18
+
19
+ # (#to_byte_string is space and case-insensitive:)
20
+ >> "776F726C64".to_byte_string
21
+ => "world"
22
+
23
+ # Peek at the first 4 bytes of an executable on OS X:
24
+ >> File.read("/bin/ls")[0..3].to_hex_string
25
+ => "ca fe ba be"
26
+
27
+ Motivation
28
+ ----------
29
+ When working with binary message or file formats, we often want to have a peek
30
+ at some segment of binary data and talk about individual byte values in
31
+ human-relatable terms.
32
+
33
+ This sort of thing comes in handy during testing, debugging and data
34
+ introspection, especially when it's inconvenient or impractical to capture the
35
+ desired binary data to file in order to view it with a hex editor or other
36
+ binary file reader.
37
+
38
+ We were inspired to publish this humble Gem after we found ourselves copying it
39
+ by hand from project to project over the course of several years.
40
+
41
+ Authors
42
+ =======
43
+ * Micah Alles (alles@atomicobject.com)
44
+ * David Crosby (crosby@atomicobject.com)
45
+ * © 2011 [Atomic Object](http://www.atomicobject.com/)
46
+ * More Atomic Object [open source](http://www.atomicobject.com/pages/Software+Commons) projects
@@ -0,0 +1,19 @@
1
+ require "bundler"
2
+ require "rake/testtask"
3
+ require "rake/clean"
4
+ require "yard"
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.test_files = FileList["test/*_test.rb"]
9
+ end
10
+
11
+ YARD::Rake::YardocTask.new do |t|
12
+ t.files = %w[ lib/hex_string.rb ]
13
+ end
14
+
15
+ CLEAN.include "pkg"
16
+ CLEAN.include "doc"
17
+ CLEAN.include ".yardoc"
18
+
19
+ task :default => :test
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "hex_string"
5
+ s.version = "1.0.0"
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = ["David Crosby", "Micah Alles"]
8
+ s.email = ["crosby@atomicobject.com", "alles@atomicobject.com"]
9
+ s.homepage = ""
10
+ s.summary = %q{String extensions to convert binary data to / from human readable hex tuples.}
11
+ s.description = %q{String extensions to convert binary data to / from human readable hex tuples.}
12
+
13
+ s.rubyforge_project = "hex_string"
14
+
15
+ s.add_development_dependency("bundler", ">= 1.0.0")
16
+ s.add_development_dependency("rake", ">= 0.8.0")
17
+ s.add_development_dependency("yard", "~> 0.6.4")
18
+ s.add_development_dependency("bluecloth", "~> 2.0.11")
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+ end
@@ -0,0 +1,43 @@
1
+ # String extensions providing to_hex_string and to_byte_string.
2
+ # Requiring hex_string will automatically include HexString in the String class.
3
+ module HexString
4
+
5
+ # Convert a human-readable hex string into binary data.
6
+ #
7
+ # Assumes the target String is an ASCII, human readable sequence of hexadecimal
8
+ # tuples depicting a sequence of 8-bit byte values.
9
+ # Whitespace between tuples is allowed and will be removed before packing.
10
+ #
11
+ # Returns a newly created string containing binary data -- the target string will not be modified.
12
+ #
13
+ # Eg:
14
+ # >> "68 65 6c 6c 6f".to\_byte\_string
15
+ # => "hello"
16
+ def to_byte_string
17
+ stripped = self.gsub(/\s+/,'')
18
+ unless stripped.size % 2 == 0
19
+ raise "Can't translate a string unless it has an even number of digits"
20
+ end
21
+ raise "Can't translate non-hex characters" if stripped =~ /[^0-9A-Fa-f]/
22
+ [stripped].pack('H*')
23
+ end
24
+
25
+ # Convert binary data into a human-readable hex string.
26
+ #
27
+ # Whatever data is contained in the target string will be "exploded" into a sequence of
28
+ # hexadecimal tuples, one space between each tuple, for ease of debugging and reading.
29
+ #
30
+ # Returns a newly created string containing the hex string -- the target binary string will not be modified.
31
+ #
32
+ # Eg:
33
+ # >> "hello world".to\_hex\_string
34
+ # => "68 65 6c 6c 6f 20 77 6f 72 6c 64"
35
+ def to_hex_string
36
+ self.unpack('H*').first.gsub(/(..)/,'\1 ').rstrip
37
+ end
38
+ end
39
+
40
+ # Include HexString extensions in the String class
41
+ class String
42
+ include HexString
43
+ end
@@ -0,0 +1,57 @@
1
+ require 'test/unit'
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/hex_string')
3
+
4
+ class HexStringTest < Test::Unit::TestCase
5
+ def self.should(behave,&block)
6
+ mname = "test_should_#{behave}"
7
+ if block
8
+ define_method mname, &block
9
+ else
10
+ puts ">>> UNIMPLEMENTED CASE: #{name.sub(/Test$/,'')} should #{behave}"
11
+ end
12
+ end
13
+
14
+ should "allow human readable hex strings to become actual byte strings" do
15
+ human = "0102030405060708090a0b0c0d0e0f"
16
+ expect = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
17
+ assert_equal expect, human.to_byte_string
18
+ end
19
+
20
+ should "not care about case of a-f or A-F" do
21
+ human = "aabbccddeeffAABBCCDDEEFF"
22
+ expect = "\xaa\xbb\xcc\xdd\xee\xff\xaa\xbb\xcc\xdd\xee\xff"
23
+ assert_equal expect, human.to_byte_string
24
+ end
25
+
26
+ should "ignore whitespace of all kinds" do
27
+ human = "\t\t\taa \t\t bb c\nc d\tdee ffAABBCCDDEEFF\t \n\r"
28
+ expect = "\xaa\xbb\xcc\xdd\xee\xff\xaa\xbb\xcc\xdd\xee\xff"
29
+ assert_equal expect, human.to_byte_string
30
+ end
31
+
32
+ should "reject odd lengths of digits" do
33
+ human = "abbccddeeffAABBCCDDEEFF"
34
+ err = assert_raise(RuntimeError) do
35
+ human.to_byte_string
36
+ end
37
+ assert_match(/even/,err.message)
38
+ assert_match(/digits/,err.message)
39
+ end
40
+
41
+ should "reject non-hex digits" do
42
+ human = "aabbccddXKeeffAABBCCDDEEFF"
43
+ err = assert_raise(RuntimeError) do
44
+ human.to_byte_string
45
+ end
46
+ assert_match(/hex/,err.message)
47
+ end
48
+
49
+ should "convert byte strings into human readable hex strings" do
50
+ assert_equal "68 65 6c 6c 6f", "hello".to_hex_string
51
+ end
52
+
53
+ should "provide empty hex strings when operating on empty strings" do
54
+ assert_equal "", "".to_hex_string
55
+ end
56
+
57
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hex_string
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - David Crosby
14
+ - Micah Alles
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-07-06 00:00:00 -04:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: bundler
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 23
31
+ segments:
32
+ - 1
33
+ - 0
34
+ - 0
35
+ version: 1.0.0
36
+ type: :development
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rake
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 63
47
+ segments:
48
+ - 0
49
+ - 8
50
+ - 0
51
+ version: 0.8.0
52
+ type: :development
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
55
+ name: yard
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 15
63
+ segments:
64
+ - 0
65
+ - 6
66
+ - 4
67
+ version: 0.6.4
68
+ type: :development
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
71
+ name: bluecloth
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ hash: 25
79
+ segments:
80
+ - 2
81
+ - 0
82
+ - 11
83
+ version: 2.0.11
84
+ type: :development
85
+ version_requirements: *id004
86
+ description: String extensions to convert binary data to / from human readable hex tuples.
87
+ email:
88
+ - crosby@atomicobject.com
89
+ - alles@atomicobject.com
90
+ executables: []
91
+
92
+ extensions: []
93
+
94
+ extra_rdoc_files: []
95
+
96
+ files:
97
+ - .gitignore
98
+ - .yardopts
99
+ - Gemfile
100
+ - README.md
101
+ - Rakefile
102
+ - hex_string.gemspec
103
+ - lib/hex_string.rb
104
+ - test/hex_string_test.rb
105
+ has_rdoc: true
106
+ homepage: ""
107
+ licenses: []
108
+
109
+ post_install_message:
110
+ rdoc_options: []
111
+
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
131
+ version: "0"
132
+ requirements: []
133
+
134
+ rubyforge_project: hex_string
135
+ rubygems_version: 1.3.7
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: String extensions to convert binary data to / from human readable hex tuples.
139
+ test_files:
140
+ - test/hex_string_test.rb