hachi64 0.1.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.
- checksums.yaml +7 -0
- data/README.md +182 -0
- data/lib/hachi64.rb +107 -0
- metadata +61 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: cf15a3dea562b3cc659afb7ea4d550c9f84e0eba3de75afc63718c03cdf03390
|
|
4
|
+
data.tar.gz: 4d3c5105fa319c23505b627e66f573ee174a3d51ab7672dc8d9ce2c0f59651ee
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 1e96d902febbdd44958b7923b633d57b4df54a7508396b3e7b0e22558d89961b6bd93af12a3a31917d28e05fd00a982c34f8bfbb8c0d63580b7bebb0b68d8175
|
|
7
|
+
data.tar.gz: e2366de73b2df4586440e90c293c7b4228fc14ae11b3e4f93635fdbc2bb8fc98fbc2a2ce127c054ef722a9ad3d230706de4645a440d51237247a56e3801a1d90
|
data/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Hachi64 Ruby Implementation
|
|
2
|
+
|
|
3
|
+
哈吉米64 编解码器的 Ruby 实现 - 使用64个中文字符进行 Base64 风格的编码和解码。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
### 从源码安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd ruby
|
|
11
|
+
gem build hachi64.gemspec
|
|
12
|
+
gem install hachi64-0.1.0.gem
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 在项目中使用
|
|
16
|
+
|
|
17
|
+
如果不想安装 gem,可以直接在项目中引用:
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
require_relative 'lib/hachi64'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 运行示例
|
|
24
|
+
|
|
25
|
+
查看并运行 `example.rb` 来了解基本用法:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ruby example.rb
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 使用方法
|
|
32
|
+
|
|
33
|
+
### 基本使用
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
require 'hachi64'
|
|
37
|
+
|
|
38
|
+
# 编码
|
|
39
|
+
data = "Hello, World!"
|
|
40
|
+
encoded = Hachi64.encode(data)
|
|
41
|
+
puts encoded # 输出: 豆米啊拢嘎米多拢迷集伽漫咖苦播库迷律==
|
|
42
|
+
|
|
43
|
+
# 解码
|
|
44
|
+
decoded = Hachi64.decode(encoded)
|
|
45
|
+
puts decoded # 输出: Hello, World!
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 不使用填充
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
# 编码时不使用填充
|
|
52
|
+
encoded = Hachi64.encode("Hello", padding: false)
|
|
53
|
+
puts encoded # 输出: 豆米啊拢嘎米多
|
|
54
|
+
|
|
55
|
+
# 解码时指定无填充
|
|
56
|
+
decoded = Hachi64.decode(encoded, padding: false)
|
|
57
|
+
puts decoded # 输出: Hello
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 处理二进制数据
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
# Hachi64 可以处理任意二进制数据
|
|
64
|
+
binary_data = File.read("image.png", mode: "rb")
|
|
65
|
+
encoded = Hachi64.encode(binary_data)
|
|
66
|
+
decoded = Hachi64.decode(encoded)
|
|
67
|
+
|
|
68
|
+
# 验证数据完整性
|
|
69
|
+
puts binary_data == decoded # 输出: true
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API 文档
|
|
73
|
+
|
|
74
|
+
### `Hachi64.encode(data, padding: true)`
|
|
75
|
+
|
|
76
|
+
将字节字符串编码为哈吉米64字符串。
|
|
77
|
+
|
|
78
|
+
**参数:**
|
|
79
|
+
- `data` (String): 要编码的数据(二进制字符串)
|
|
80
|
+
- `padding` (Boolean): 是否使用 `=` 进行填充(默认为 `true`)
|
|
81
|
+
|
|
82
|
+
**返回:**
|
|
83
|
+
- (String): 编码后的字符串
|
|
84
|
+
|
|
85
|
+
**示例:**
|
|
86
|
+
```ruby
|
|
87
|
+
Hachi64.encode("Hello") # => "豆米啊拢嘎米多="
|
|
88
|
+
Hachi64.encode("Hello", padding: false) # => "豆米啊拢嘎米多"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `Hachi64.decode(encoded_str, padding: true)`
|
|
92
|
+
|
|
93
|
+
将哈吉米64字符串解码为字节字符串。
|
|
94
|
+
|
|
95
|
+
**参数:**
|
|
96
|
+
- `encoded_str` (String): 要解码的字符串
|
|
97
|
+
- `padding` (Boolean): 输入字符串是否使用 `=` 进行填充(应与编码时的设置一致,默认为 `true`)
|
|
98
|
+
|
|
99
|
+
**返回:**
|
|
100
|
+
- (String): 解码后的字节字符串
|
|
101
|
+
|
|
102
|
+
**异常:**
|
|
103
|
+
- `ArgumentError`: 如果输入包含无效字符
|
|
104
|
+
|
|
105
|
+
**示例:**
|
|
106
|
+
```ruby
|
|
107
|
+
Hachi64.decode("豆米啊拢嘎米多=") # => "Hello"
|
|
108
|
+
Hachi64.decode("豆米啊拢嘎米多", padding: false) # => "Hello"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `Hachi64::HACHI_ALPHABET`
|
|
112
|
+
|
|
113
|
+
哈吉米64字符集常量,包含64个中文字符。
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
puts Hachi64::HACHI_ALPHABET
|
|
117
|
+
# => "哈蛤呵吉急集米咪迷南男难北背杯绿律虑豆斗抖啊阿额西希息嘎咖伽花华哗压鸭呀库酷苦奶乃耐龙隆拢曼慢漫波播玻叮丁订咚东冬囊路陆多都弥济"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 编码示例
|
|
121
|
+
|
|
122
|
+
以下是一些使用哈吉米64编码的示例:
|
|
123
|
+
|
|
124
|
+
| 原始数据 | 编码结果 |
|
|
125
|
+
|---------|---------|
|
|
126
|
+
| `Hello` | `豆米啊拢嘎米多=` |
|
|
127
|
+
| `abc` | `西阿南呀` |
|
|
128
|
+
| `Python` | `抖咪酷丁息米都慢` |
|
|
129
|
+
| `Hello, World!` | `豆米啊拢嘎米多拢迷集伽漫咖苦播库迷律==` |
|
|
130
|
+
| `Base64` | `律苦集叮希斗西丁` |
|
|
131
|
+
| `Hachi64` | `豆米集呀息米库咚背哈==` |
|
|
132
|
+
|
|
133
|
+
## 测试
|
|
134
|
+
|
|
135
|
+
运行单元测试:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
cd ruby
|
|
139
|
+
bundle install # 安装开发依赖
|
|
140
|
+
bundle exec rspec
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
或者直接使用 RSpec(如果已全局安装):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cd ruby
|
|
147
|
+
rspec
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## 特性
|
|
151
|
+
|
|
152
|
+
- ✅ 完整的编码/解码功能
|
|
153
|
+
- ✅ 支持有/无填充模式
|
|
154
|
+
- ✅ 处理任意二进制数据
|
|
155
|
+
- ✅ 与其他语言实现兼容
|
|
156
|
+
- ✅ 完整的 RSpec 测试覆盖
|
|
157
|
+
- ✅ 清晰的错误处理
|
|
158
|
+
- ✅ 符合 Ruby 编码规范
|
|
159
|
+
|
|
160
|
+
## 开发
|
|
161
|
+
|
|
162
|
+
### 安装依赖
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
bundle install
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 运行测试
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
bundle exec rspec
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 构建 gem
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
gem build hachi64.gemspec
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 许可证
|
|
181
|
+
|
|
182
|
+
本项目遵循父项目的许可证。
|
data/lib/hachi64.rb
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Hachi64: 哈吉米64 Encoding and Decoding
|
|
4
|
+
# This module provides encoding and decoding using the Hachi64 character set.
|
|
5
|
+
|
|
6
|
+
module Hachi64
|
|
7
|
+
# The Hachi64 alphabet - 64 unique Chinese characters
|
|
8
|
+
HACHI_ALPHABET = "哈蛤呵吉急集米咪迷南男难北背杯绿律虑豆斗抖啊阿额西希息嘎咖伽花华哗压鸭呀库酷苦奶乃耐龙隆拢曼慢漫波播玻叮丁订咚东冬囊路陆多都弥济"
|
|
9
|
+
|
|
10
|
+
# Encodes a byte string into a Hachi64 string using the Hachi64 alphabet.
|
|
11
|
+
#
|
|
12
|
+
# @param data [String] The bytes to encode (binary string)
|
|
13
|
+
# @param padding [Boolean] Whether to use '=' for padding (default: true)
|
|
14
|
+
# @return [String] The encoded string
|
|
15
|
+
def self.encode(data, padding: true)
|
|
16
|
+
alphabet = HACHI_ALPHABET
|
|
17
|
+
result = []
|
|
18
|
+
data_len = data.bytesize
|
|
19
|
+
i = 0
|
|
20
|
+
|
|
21
|
+
while i < data_len
|
|
22
|
+
chunk = data.byteslice(i, 3)
|
|
23
|
+
i += 3
|
|
24
|
+
|
|
25
|
+
byte1 = chunk.getbyte(0)
|
|
26
|
+
byte2 = chunk.bytesize > 1 ? chunk.getbyte(1) : 0
|
|
27
|
+
byte3 = chunk.bytesize > 2 ? chunk.getbyte(2) : 0
|
|
28
|
+
|
|
29
|
+
idx1 = byte1 >> 2
|
|
30
|
+
idx2 = ((byte1 & 0x03) << 4) | (byte2 >> 4)
|
|
31
|
+
idx3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6)
|
|
32
|
+
idx4 = byte3 & 0x3F
|
|
33
|
+
|
|
34
|
+
result << alphabet[idx1]
|
|
35
|
+
result << alphabet[idx2]
|
|
36
|
+
|
|
37
|
+
if chunk.bytesize > 1
|
|
38
|
+
result << alphabet[idx3]
|
|
39
|
+
elsif padding
|
|
40
|
+
result << '='
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if chunk.bytesize > 2
|
|
44
|
+
result << alphabet[idx4]
|
|
45
|
+
elsif padding
|
|
46
|
+
result << '='
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
result.join
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Decodes a Hachi64 string into bytes using the Hachi64 alphabet.
|
|
54
|
+
#
|
|
55
|
+
# @param encoded_str [String] The string to decode
|
|
56
|
+
# @param padding [Boolean] Whether the input string uses '=' for padding (default: true)
|
|
57
|
+
# @return [String] The decoded bytes (binary string)
|
|
58
|
+
# @raise [ArgumentError] If the input string contains invalid characters
|
|
59
|
+
def self.decode(encoded_str, padding: true)
|
|
60
|
+
alphabet = HACHI_ALPHABET
|
|
61
|
+
reverse_map = {}
|
|
62
|
+
alphabet.each_char.with_index { |char, i| reverse_map[char] = i }
|
|
63
|
+
|
|
64
|
+
# Handle empty string
|
|
65
|
+
return ''.b if encoded_str.empty?
|
|
66
|
+
|
|
67
|
+
pad_count = 0
|
|
68
|
+
if padding
|
|
69
|
+
pad_count = encoded_str.count('=')
|
|
70
|
+
if pad_count > 0
|
|
71
|
+
encoded_str = encoded_str[0...-pad_count]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
result = []
|
|
76
|
+
data_len = encoded_str.length
|
|
77
|
+
i = 0
|
|
78
|
+
|
|
79
|
+
while i < data_len
|
|
80
|
+
chunk_end = [i + 4, data_len].min
|
|
81
|
+
chunk = encoded_str[i...chunk_end]
|
|
82
|
+
i += 4
|
|
83
|
+
|
|
84
|
+
idx1 = reverse_map[chunk[0]]
|
|
85
|
+
idx2 = chunk.length > 1 ? reverse_map[chunk[1]] : 0
|
|
86
|
+
idx3 = chunk.length > 2 ? reverse_map[chunk[2]] : 0
|
|
87
|
+
idx4 = chunk.length > 3 ? reverse_map[chunk[3]] : 0
|
|
88
|
+
|
|
89
|
+
raise ArgumentError, "Invalid character in input" if idx1.nil? || (chunk.length > 1 && idx2.nil?)
|
|
90
|
+
|
|
91
|
+
byte1 = (idx1 << 2) | (idx2 >> 4)
|
|
92
|
+
result << byte1
|
|
93
|
+
|
|
94
|
+
if chunk.length > 2
|
|
95
|
+
byte2 = ((idx2 & 0x0F) << 4) | (idx3 >> 2)
|
|
96
|
+
result << byte2
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if chunk.length > 3
|
|
100
|
+
byte3 = ((idx3 & 0x03) << 6) | idx4
|
|
101
|
+
result << byte3
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
result.pack('C*')
|
|
106
|
+
end
|
|
107
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: hachi64
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- fengb3
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-11-10 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.12'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.12'
|
|
27
|
+
description: Hachi64 provides encoding and decoding using a custom 64-character Chinese
|
|
28
|
+
character set, similar to Base64 but with Hachimi-style characters.
|
|
29
|
+
email: []
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- README.md
|
|
35
|
+
- lib/hachi64.rb
|
|
36
|
+
homepage: https://github.com/fengb3/Hachi64
|
|
37
|
+
licenses:
|
|
38
|
+
- MIT
|
|
39
|
+
metadata:
|
|
40
|
+
homepage_uri: https://github.com/fengb3/Hachi64
|
|
41
|
+
source_code_uri: https://github.com/fengb3/Hachi64
|
|
42
|
+
post_install_message:
|
|
43
|
+
rdoc_options: []
|
|
44
|
+
require_paths:
|
|
45
|
+
- lib
|
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: 2.6.0
|
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
requirements: []
|
|
57
|
+
rubygems_version: 3.4.19
|
|
58
|
+
signing_key:
|
|
59
|
+
specification_version: 4
|
|
60
|
+
summary: 哈吉米64 encoding and decoding
|
|
61
|
+
test_files: []
|