Skip to content

Commit 478601c

Browse files
committed
up bytes
1 parent 5f668ab commit 478601c

File tree

12 files changed

+403
-0
lines changed

12 files changed

+403
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
Gems:
44

5+
- [**bytes**](bytes) - bits 'n' bytes made easy/easier incl. new buffer helper / wrapper class to help with the string byte vs character dichotomy
56
- [**enums**](enums) - safe enum / enumeration types - a set of symbolic keys bound to unique integer numbers (incl. bit flags option)
67

78
<!-- break -->

bytes/.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
*.gem
2+
*.rbc
3+
/.config
4+
/coverage/
5+
/InstalledFiles
6+
/pkg/
7+
/spec/reports/
8+
/test/tmp/
9+
/test/version_tmp/
10+
/tmp/
11+
12+
## Specific to RubyMotion:
13+
.dat*
14+
.repl_history
15+
build/
16+
17+
## Documentation cache and generated files:
18+
/.yardoc/
19+
/_yardoc/
20+
/doc/
21+
/rdoc/
22+
23+
## Environment normalisation:
24+
/.bundle/
25+
/vendor/bundle
26+
/lib/bundler/man/
27+
28+
# for a library or gem, you might want to ignore these files since the code is
29+
# intended to run in multiple environments; otherwise, check them in:
30+
# Gemfile.lock
31+
# .ruby-version
32+
# .ruby-gemset
33+
34+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35+
.rvmrc

bytes/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### 0.0.1 / 2019-04-16
2+
3+
* Everything is new. First release

bytes/Manifest.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CHANGELOG.md
2+
LICENSE.md
3+
Manifest.txt
4+
README.md
5+
Rakefile
6+
lib/bytes.rb
7+
lib/bytes/version.rb
8+
test/helper.rb
9+
test/test_bytes.rb
10+
test/test_hash.rb
11+
test/test_string.rb

bytes/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
# Bytes
3+
4+
bytes - bits 'n' bytes made easy/easier incl. new buffer helper / wrapper class to help with the string byte vs character dichotomy
5+
6+
* home :: [github.com/typesigs/bytes](https://github.com/typesigs/bytes)
7+
* bugs :: [github.com/typesigs/bytes/issues](https://github.com/typesigs/bytes/issues)
8+
* gem :: [rubygems.org/gems/bytes](https://rubygems.org/gems/bytes)
9+
* rdoc :: [rubydoc.info/gems/bytes](http://rubydoc.info/gems/bytes)
10+
11+
12+
13+
## Usage
14+
15+
To be done
16+
17+
18+
## License
19+
20+
![](https://publicdomainworks.github.io/buttons/zero88x31.png)
21+
22+
The `bytes` scripts are dedicated to the public domain.
23+
Use it as you please with no restrictions whatsoever.
24+
25+
26+
## Questions? Comments?
27+
28+
Send them along to the [wwwmake forum](http://groups.google.com/group/wwwmake).
29+
Thanks!

bytes/Rakefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'hoe'
2+
require './lib/bytes/version.rb'
3+
4+
Hoe.spec 'bytes' do
5+
6+
self.version = Bytes::VERSION
7+
8+
self.summary = "bytes"
9+
self.description = summary
10+
11+
self.urls = ['https://github.com/typesigs/bytes']
12+
13+
self.author = 'Gerald Bauer'
14+
self.email = 'wwwmake@googlegroups.com'
15+
16+
# switch extension to .markdown for gihub formatting
17+
self.readme_file = 'README.md'
18+
self.history_file = 'CHANGELOG.md'
19+
20+
self.extra_deps = [
21+
]
22+
23+
self.licenses = ['Public Domain']
24+
25+
self.spec_extras = {
26+
required_ruby_version: '>= 2.2.2'
27+
}
28+
29+
end

bytes/lib/bytes.rb

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# encoding: utf-8
2+
3+
require 'pp'
4+
require 'digest'
5+
6+
7+
## our own code
8+
require 'bytes/version' # note: let version always go first
9+
10+
11+
class Bytes
12+
def self.new( *args )
13+
String.new( *args ).b
14+
end
15+
16+
def self.from_hex( hexstr )
17+
if ['0x', '0X'].include?( hexstr[0...2] )
18+
[hexstr[2..-1]].pack('H*') ## cut-of leading 0x or 0X if present
19+
else
20+
[hexstr].pack('H*')
21+
end
22+
end
23+
24+
def self.to_hex( str )
25+
# note: unpack returns string with <Encoding:US-ASCII>
26+
# conver to default encoding
27+
## todo/fix: do NOT hardcode UTF-8 - use default encoding - how?
28+
str.unpack('H*').first.encode("UTF-8")
29+
end
30+
31+
def self.convert( *args )
32+
## used by Bytes() in global Kernel converter method
33+
if args.size == 1
34+
if args[0].is_a? Array
35+
## assume array of bytes
36+
## to be done
37+
else ## assume String
38+
## todo/fix: use coerce to_str if arg is NOT a string - why? why not?
39+
str = args[0]
40+
##
41+
if str.encoding == Encoding::ASCII_8BIT
42+
## assume it's binary data - use as is (no hexstring conversion)
43+
new( str ) ## todo/check: return str as-is (without new) - why? why not?
44+
else ## assume it's a hexstring
45+
from_hex( str )
46+
end
47+
end
48+
else
49+
## todo/fix: throw argument error
50+
end
51+
end
52+
end
53+
54+
55+
class Buffer
56+
def self.new( *args )
57+
if args.size == 0
58+
## note: use "" to always use default encoding (and NOT binary)
59+
String.new( "" )
60+
else
61+
String.new( *args )
62+
end
63+
end
64+
end
65+
66+
67+
module BytesHelper
68+
def hex_to_bytes( hexstr ) Bytes.from_hex( hexstr); end
69+
alias_method :h_to_b, :hex_to_bytes
70+
alias_method :htob, :hex_to_bytes
71+
72+
def bytes_to_hex( str ) Bytes.to_hex( str ); end
73+
alias_method :b_to_h, :bytes_to_hex
74+
alias_method :btoh, :bytes_to_hex
75+
end
76+
77+
78+
79+
class String
80+
def h_to_b() Bytes.from_hex( self ); end
81+
alias_method :htob, :h_to_b
82+
83+
def b_to_h() Bytes.to_hex( self ); end ## add .b-like shortcut
84+
alias_method :btoh, :b_to_h
85+
alias_method :h, :b_to_h
86+
end
87+
88+
89+
module HashHelper
90+
def sha256( bytes )
91+
## todo/fix: check bytes.encoding - warn if not BINARY!!!!
92+
Digest::SHA256.digest( bytes )
93+
end
94+
95+
def ripemd160( bytes )
96+
## todo/fix: check bytes.encoding - warn if not BINARY!!!!
97+
Digest::RMD160.digest( bytes )
98+
end
99+
100+
def hash256( bytes )
101+
## double - uses sha256(sha256())
102+
sha256(sha256( bytes ))
103+
end
104+
105+
def hash160( bytes )
106+
## double - uses ripemd160(sha256())
107+
ripemd160(sha256( bytes ))
108+
end
109+
110+
## convenience shortcut helpers
111+
def sha256hex( bytes ) Bytes.to_hex(sha256( bytes )); end
112+
def ripemd160hex( bytes ) Bytes.to_hex(ripemd160( bytes )); end
113+
def hash256( bytes ) Bytes.to_hex(hash256( bytes )); end
114+
def hash160( bytes ) Bytes.to_hex(hash160( bytes )); end
115+
end
116+
117+
## make "global" for now - check if there's a better way (include in Kernel) - why? why ot?
118+
include HashHelper
119+
include BytesHelper
120+
121+
122+
123+
module Kernel
124+
def Bytes( *args ) Bytes.convert( *args ); end
125+
end
126+
127+
puts Bytes.banner ## say hello

bytes/lib/bytes/version.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# encoding: utf-8
2+
3+
4+
5+
class Bytes
6+
7+
MAJOR = 0
8+
MINOR = 1
9+
PATCH = 0
10+
VERSION = [MAJOR,MINOR,PATCH].join('.')
11+
12+
def self.version
13+
VERSION
14+
end
15+
16+
def self.banner
17+
"bytes/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
18+
end
19+
20+
def self.root
21+
"#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
22+
end
23+
24+
end # class Bytes

bytes/test/helper.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## minitest setup
2+
3+
require 'minitest/autorun'
4+
5+
6+
## our own code
7+
8+
require 'bytes'

bytes/test/test_bytes.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# encoding: utf-8
2+
3+
###
4+
# to run use
5+
# ruby -I ./lib -I ./test test/test_bytes.rb
6+
7+
8+
require 'helper'
9+
10+
11+
class TestBytes < MiniTest::Test
12+
13+
def test_hex
14+
assert String.new( "6162") == Bytes.to_hex( "ab" )
15+
assert String.new( "6162") == bytes_to_hex( "ab" )
16+
assert String.new( "6162") == "ab".b_to_h
17+
assert String.new( "6162") == "ab".btoh
18+
assert String.new( "6162") == "ab".h
19+
assert String.new( "6162") == Bytes.to_hex( "\x61\x62" )
20+
assert String.new( "6162") == bytes_to_hex( "\x61\x62" )
21+
assert String.new( "6162") == "\x61\x62".b_to_h
22+
assert String.new( "6162") == "\x61\x62".btoh
23+
assert String.new( "6162") == "\x61\x62".h
24+
assert Encoding::UTF_8 == Bytes.to_hex( "ab" ).encoding
25+
26+
assert Bytes.new( "ab" ) == Bytes.from_hex( "6162" )
27+
assert Bytes.new( "ab" ) == hex_to_bytes( "6162" )
28+
assert Bytes.new( "ab" ) == "6162".h_to_b
29+
assert Bytes.new( "ab" ) == "6162".htob
30+
assert Bytes.new( "ab" ) == Bytes.from_hex( "0x6162" )
31+
assert Bytes.new( "ab" ) == hex_to_bytes( "0x6162" )
32+
assert Bytes.new( "ab" ) == "0x6162".h_to_b
33+
assert Bytes.new( "ab" ) == "0x6162".htob
34+
assert Encoding::ASCII_8BIT == Bytes.from_hex( "6162" ).encoding
35+
36+
assert Bytes.new( "ab" ) == Bytes( "6162" )
37+
assert Bytes.new( "ab" ) == Bytes( "0x6162" )
38+
assert Bytes.new( "6162" ) == Bytes( "6162".b )
39+
assert Bytes.new( "ab" ) == Bytes( "ab".b )
40+
assert Bytes.new( "ab") == Bytes( "\x61\x62".b )
41+
assert Encoding::ASCII_8BIT == Bytes( "6162" ).encoding
42+
assert Encoding::ASCII_8BIT == Bytes( "6162".b ).encoding
43+
assert Encoding::ASCII_8BIT == Bytes( "ab".b ).encoding
44+
end
45+
46+
end # class TestBytes

0 commit comments

Comments
 (0)