philiprehberger-hex 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 27120f5b94f3fc6caff3242cb9a368571f59f8f3f7e27318acd36ad728ab7932
4
+ data.tar.gz: d72f73c7bf1f89d494af6c35a7bd42faf692feccf6a0bf37bd8eb6a66a6f5309
5
+ SHA512:
6
+ metadata.gz: 942dae412ae29a010081d6dc0a83dbe975cceeb3ef9437fe5b078bb1e3241e8bdcb325b203016ae20e429d74e16803ba8feff1c167120c0b2996a13e18dd1c90
7
+ data.tar.gz: bd8559b024e501599b0a5a2e0dacb0f6c799e559ddc9ae5ea06f4a41af73301765ee3fab6a076a84b7de4812f728f0270a07c5f1ffad09cae496fd6d64fffa0e
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this gem will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-03-22
11
+
12
+ ### Added
13
+
14
+ - Initial release
15
+ - Hex encoding and decoding
16
+ - xxd-style hex dump output
17
+ - Configurable hex grouping format
18
+ - Hex string validation
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 philiprehberger
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # philiprehberger-hex
2
+
3
+ [![Tests](https://github.com/philiprehberger/rb-hex/actions/workflows/ci.yml/badge.svg)](https://github.com/philiprehberger/rb-hex/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/philiprehberger-hex.svg)](https://rubygems.org/gems/philiprehberger-hex)
5
+ [![License](https://img.shields.io/github/license/philiprehberger/rb-hex)](LICENSE)
6
+
7
+ Hex encoding, decoding, and dump formatting for binary data
8
+
9
+ ## Requirements
10
+
11
+ - Ruby >= 3.1
12
+
13
+ ## Installation
14
+
15
+ Add to your Gemfile:
16
+
17
+ ```ruby
18
+ gem 'philiprehberger-hex'
19
+ ```
20
+
21
+ Or install directly:
22
+
23
+ ```bash
24
+ gem install philiprehberger-hex
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```ruby
30
+ require 'philiprehberger/hex'
31
+
32
+ Philiprehberger::Hex.encode('hello') # => "68656c6c6f"
33
+ Philiprehberger::Hex.decode('68656c6c6f') # => "hello"
34
+ ```
35
+
36
+ ### Hex Dump
37
+
38
+ ```ruby
39
+ Philiprehberger::Hex.dump("Hello, World!\n")
40
+ # 00000000: 4865 6c6c 6f2c 2057 6f72 6c64 210a Hello, World!.
41
+ ```
42
+
43
+ ### Grouped Format
44
+
45
+ ```ruby
46
+ Philiprehberger::Hex.format('hello', group: 1) # => "68 65 6c 6c 6f"
47
+ Philiprehberger::Hex.format('hello', group: 2) # => "6865 6c6c 6f"
48
+ ```
49
+
50
+ ### Validation
51
+
52
+ ```ruby
53
+ Philiprehberger::Hex.valid?('abcdef') # => true
54
+ Philiprehberger::Hex.valid?('xyz') # => false
55
+ ```
56
+
57
+ ## API
58
+
59
+ | Method | Description |
60
+ |--------|-------------|
61
+ | `Hex.encode(str)` | Encode a string to hexadecimal |
62
+ | `Hex.decode(hex)` | Decode a hexadecimal string to binary |
63
+ | `Hex.dump(str)` | Produce an xxd-style hex dump |
64
+ | `Hex.format(str, group:)` | Format hex output with configurable grouping |
65
+ | `Hex.valid?(str)` | Check if a string is valid hexadecimal |
66
+
67
+ ## Development
68
+
69
+ ```bash
70
+ bundle install
71
+ bundle exec rspec # Run tests
72
+ bundle exec rubocop # Check code style
73
+ ```
74
+
75
+ ## License
76
+
77
+ MIT
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philiprehberger
4
+ module Hex
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'hex/version'
4
+
5
+ module Philiprehberger
6
+ module Hex
7
+ class Error < StandardError; end
8
+
9
+ HEX_PATTERN = /\A[0-9a-fA-F]*\z/
10
+
11
+ def self.validate_string!(str)
12
+ raise Error, 'expected a String' unless str.is_a?(String)
13
+ end
14
+
15
+ private_class_method :validate_string!
16
+
17
+ # Encode a string to hexadecimal
18
+ #
19
+ # @param str [String]
20
+ # @return [String] hex-encoded string
21
+ def self.encode(str)
22
+ validate_string!(str)
23
+ str.unpack1('H*')
24
+ end
25
+
26
+ # Decode a hexadecimal string to binary
27
+ #
28
+ # @param hex [String] hex-encoded string
29
+ # @return [String] decoded binary string
30
+ def self.decode(hex)
31
+ validate_string!(hex)
32
+ raise Error, 'invalid hex string: odd length' if hex.length.odd?
33
+ raise Error, 'invalid hex string: non-hex characters' unless valid?(hex)
34
+
35
+ [hex].pack('H*')
36
+ end
37
+
38
+ # Produce an xxd-style hex dump
39
+ #
40
+ # @param str [String]
41
+ # @return [String] formatted hex dump
42
+ def self.dump(str)
43
+ validate_string!(str)
44
+ lines = []
45
+ bytes = str.bytes
46
+
47
+ bytes.each_slice(16).with_index do |chunk, index|
48
+ offset = Kernel.format('%08x', index * 16)
49
+ hex_part = chunk.each_slice(2).map { |pair| pair.map { |b| Kernel.format('%02x', b) }.join }.join(' ')
50
+ ascii_part = chunk.map { |b| b.between?(32, 126) ? b.chr : '.' }.join
51
+ lines << Kernel.format('%-10s %-40s %s', "#{offset}:", hex_part, ascii_part)
52
+ end
53
+
54
+ lines.join("\n")
55
+ end
56
+
57
+ # Format a string as grouped hex
58
+ #
59
+ # @param str [String]
60
+ # @param group [Integer] number of bytes per group
61
+ # @return [String] grouped hex string
62
+ def self.format(str, group: 2)
63
+ validate_string!(str)
64
+ hex = encode(str)
65
+ hex.scan(/.{1,#{group * 2}}/).join(' ')
66
+ end
67
+
68
+ # Check if a string is valid hexadecimal
69
+ #
70
+ # @param str [String]
71
+ # @return [Boolean]
72
+ def self.valid?(str)
73
+ return false unless str.is_a?(String)
74
+ return false if str.empty?
75
+
76
+ HEX_PATTERN.match?(str)
77
+ end
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: philiprehberger-hex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Philip Rehberger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Encode and decode hexadecimal strings, produce xxd-style hex dumps, format
14
+ hex output with configurable grouping, and validate hex strings.
15
+ email:
16
+ - me@philiprehberger.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - LICENSE
23
+ - README.md
24
+ - lib/philiprehberger/hex.rb
25
+ - lib/philiprehberger/hex/version.rb
26
+ homepage: https://github.com/philiprehberger/rb-hex
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ homepage_uri: https://github.com/philiprehberger/rb-hex
31
+ source_code_uri: https://github.com/philiprehberger/rb-hex
32
+ changelog_uri: https://github.com/philiprehberger/rb-hex/blob/main/CHANGELOG.md
33
+ bug_tracker_uri: https://github.com/philiprehberger/rb-hex/issues
34
+ rubygems_mfa_required: 'true'
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 3.1.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.5.22
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Hex encoding, decoding, and dump formatting for binary data
54
+ test_files: []