rqrcode_core 0.1.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile.lock +34 -5
- data/README.md +37 -13
- data/Rakefile +17 -8
- data/lib/rqrcode_core.rb +0 -1
- data/lib/rqrcode_core/qrcode.rb +9 -9
- data/lib/rqrcode_core/qrcode/qr_8bit_byte.rb +4 -12
- data/lib/rqrcode_core/qrcode/qr_alphanumeric.rb +18 -25
- data/lib/rqrcode_core/qrcode/qr_bit_buffer.rb +15 -25
- data/lib/rqrcode_core/qrcode/qr_code.rb +258 -258
- data/lib/rqrcode_core/qrcode/qr_math.rb +9 -10
- data/lib/rqrcode_core/qrcode/qr_numeric.rb +9 -20
- data/lib/rqrcode_core/qrcode/qr_polynomial.rb +15 -15
- data/lib/rqrcode_core/qrcode/qr_rs_block.rb +8 -10
- data/lib/rqrcode_core/qrcode/qr_util.rb +51 -47
- data/lib/rqrcode_core/version.rb +1 -1
- data/rqrcode_core.gemspec +18 -18
- metadata +22 -11
- data/lib/rqrcode_core/core_ext.rb +0 -4
- data/lib/rqrcode_core/core_ext/array.rb +0 -7
- data/lib/rqrcode_core/core_ext/array/behavior.rb +0 -14
- data/lib/rqrcode_core/core_ext/integer.rb +0 -7
- data/lib/rqrcode_core/core_ext/integer/bitwise.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc2b513b4aa28453c231e4fa52d53c4406bf03bbba9df84ab87eed0e22193389
|
4
|
+
data.tar.gz: fc7b7bfc2ad40315031899501b94a1b2a35c8987b6eeff9cd9c71d77b4e5d3d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de4b6fdb7ab8f356fb55aedbc93fb949f51f1f68acebdc1aa7d4b82ecf90cf785065104bbf68170ea39f20671ff513c5eb212cbbdb42f38f099f133612d70d17
|
7
|
+
data.tar.gz: 0a2e8ea5a6e0a2bf43a9d94a3333cc95d6558f47f6369dd5a07107e12079db85b8a21dec57ef31920a855648c96e630fc68d40942e3f9e4570a6f2f07b4c1ee5
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: rqrcode_core
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
- release/*
|
8
|
+
pull_request:
|
9
|
+
branches:
|
10
|
+
- master
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
Build:
|
14
|
+
strategy:
|
15
|
+
fail-fast: false
|
16
|
+
matrix:
|
17
|
+
os: [ubuntu-latest, macos-latest]
|
18
|
+
ruby: [2.5, 2.6, 2.7, 3.0]
|
19
|
+
runs-on: ${{ matrix.os }}
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v1
|
22
|
+
- uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
25
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
26
|
+
- name: Run Tests
|
27
|
+
run: bundle exec rake test
|
28
|
+
- name: StandardRB Check
|
29
|
+
run: bundle exec standardrb --format progress
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project 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 project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [1.1.0] - 2021-07-01
|
11
|
+
|
12
|
+
- Add a basic benchmark file
|
13
|
+
- Add standardRB badge
|
14
|
+
- Add `.freeze` on `CONST` lookup objects
|
15
|
+
- Remove unused `@mode` instance variable
|
16
|
+
- A batch of small refactors and optimizations
|
17
|
+
|
18
|
+
## [1.0.0] - 2021-04-23
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- README updated
|
23
|
+
- Small documentation clarification [@smnscp](https://github.com/smnscp).
|
24
|
+
- Rakefile cleaned up. You can now just run `rake` which will run specs and fix linting using `standardrb`
|
25
|
+
|
26
|
+
### Breaking Changes
|
27
|
+
|
28
|
+
- Very niche but a breaking change never the less. The `to_s` method *no longer* accepts the `:true` and `:false` arguments, but prefers `:dark` and `:light`.
|
29
|
+
|
30
|
+
## [0.2.0] - 2020-12-26
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
|
34
|
+
- fix `required_ruby_version` for Ruby 3 support
|
35
|
+
|
36
|
+
[unreleased]: https://github.com/whomwah/rqrcode_core/compare/v1.1.0...HEAD
|
37
|
+
[1.1.0]: https://github.com/whomwah/rqrcode_core/compare/v1.0.0...v1.1.0
|
38
|
+
[1.0.0]: https://github.com/whomwah/rqrcode_core/compare/v0.2.0...v1.0.0
|
39
|
+
[0.2.0]: https://github.com/whomwah/rqrcode_core/compare/v0.1.2...v0.2.0
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,41 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rqrcode_core (
|
4
|
+
rqrcode_core (1.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
|
10
|
-
|
9
|
+
ast (2.4.2)
|
10
|
+
minitest (5.14.4)
|
11
|
+
parallel (1.20.1)
|
12
|
+
parser (3.0.1.0)
|
13
|
+
ast (~> 2.4.1)
|
14
|
+
rainbow (3.0.0)
|
15
|
+
rake (13.0.3)
|
16
|
+
regexp_parser (2.1.1)
|
17
|
+
rexml (3.2.5)
|
18
|
+
rubocop (1.12.1)
|
19
|
+
parallel (~> 1.10)
|
20
|
+
parser (>= 3.0.0.0)
|
21
|
+
rainbow (>= 2.2.2, < 4.0)
|
22
|
+
regexp_parser (>= 1.8, < 3.0)
|
23
|
+
rexml
|
24
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
25
|
+
ruby-progressbar (~> 1.7)
|
26
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
27
|
+
rubocop-ast (1.4.1)
|
28
|
+
parser (>= 2.7.1.5)
|
29
|
+
rubocop-performance (1.10.1)
|
30
|
+
rubocop (>= 0.90.0, < 2.0)
|
31
|
+
rubocop-ast (>= 0.4.0)
|
32
|
+
ruby-progressbar (1.11.0)
|
33
|
+
standard (1.0.5)
|
34
|
+
rubocop (= 1.12.1)
|
35
|
+
rubocop-performance (= 1.10.1)
|
36
|
+
standardrb (1.0.0)
|
37
|
+
standard
|
38
|
+
unicode-display_width (2.0.0)
|
11
39
|
|
12
40
|
PLATFORMS
|
13
41
|
ruby
|
@@ -15,8 +43,9 @@ PLATFORMS
|
|
15
43
|
DEPENDENCIES
|
16
44
|
bundler (~> 2.0)
|
17
45
|
minitest (~> 5.0)
|
18
|
-
rake (~>
|
46
|
+
rake (~> 13.0)
|
19
47
|
rqrcode_core!
|
48
|
+
standardrb (~> 1.0)
|
20
49
|
|
21
50
|
BUNDLED WITH
|
22
|
-
2.
|
51
|
+
2.2.15
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
![](https://github.com/whomwah/rqrcode_core/actions/workflows/ruby.yml/badge.svg)
|
2
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
|
2
3
|
|
3
4
|
# RQRCodeCore
|
4
5
|
|
@@ -6,7 +7,7 @@
|
|
6
7
|
|
7
8
|
Features:
|
8
9
|
|
9
|
-
* `rqrcode_core` is a
|
10
|
+
* `rqrcode_core` is a Ruby only library. It requires no native libraries. Just Ruby!
|
10
11
|
* It is an encoding library. You can't decode QR codes with it.
|
11
12
|
* The interface is simple and assumes you just want to encode a string into a QR code.
|
12
13
|
* QR code is trademarked by Denso Wave inc.
|
@@ -18,7 +19,7 @@ Features:
|
|
18
19
|
Add this line to your application's Gemfile:
|
19
20
|
|
20
21
|
```ruby
|
21
|
-
gem
|
22
|
+
gem "rqrcode_core"
|
22
23
|
```
|
23
24
|
|
24
25
|
And then execute:
|
@@ -32,8 +33,8 @@ Or install it yourself as:
|
|
32
33
|
## Basic Usage
|
33
34
|
|
34
35
|
```ruby
|
35
|
-
$ require
|
36
|
-
$ qr = RQRCodeCore::QRCode.new(
|
36
|
+
$ require "rqrcode_core"
|
37
|
+
$ qr = RQRCodeCore::QRCode.new("https://kyan.com")
|
37
38
|
$ puts qr.to_s
|
38
39
|
```
|
39
40
|
|
@@ -49,12 +50,12 @@ x xxx x xxxxx x xx x xxx x
|
|
49
50
|
## Doing your own rendering
|
50
51
|
|
51
52
|
```ruby
|
52
|
-
require
|
53
|
+
require "rqrcode_core"
|
53
54
|
|
54
|
-
qr = RQRCodeCore::QRCode.new(
|
55
|
-
qr.
|
55
|
+
qr = RQRCodeCore::QRCode.new("https://kyan.com")
|
56
|
+
qr.rows.each do |row|
|
56
57
|
row.each do |col|
|
57
|
-
print col ?
|
58
|
+
print col ? "#" : " "
|
58
59
|
end
|
59
60
|
|
60
61
|
print "\n"
|
@@ -68,7 +69,7 @@ The library expects a string to be parsed in, other args are optional.
|
|
68
69
|
```
|
69
70
|
string - the string you wish to encode
|
70
71
|
|
71
|
-
size - the size of the qrcode (
|
72
|
+
size - the size (integer) of the qrcode (defaults to smallest size needed to encode the string)
|
72
73
|
|
73
74
|
level - the error correction level, can be:
|
74
75
|
* Level :l 7% of code can be restored
|
@@ -85,13 +86,36 @@ mode - the mode of the qrcode (defaults to alphanumeric or byte_8bit, dependin
|
|
85
86
|
|
86
87
|
#### Example
|
87
88
|
|
88
|
-
```
|
89
|
-
|
89
|
+
```ruby
|
90
|
+
RQRCodeCore::QRCode.new("http://kyan.com", size: 1, level: :m, mode: :alphanumeric)
|
90
91
|
```
|
91
92
|
|
92
93
|
## Development
|
93
94
|
|
94
|
-
|
95
|
+
### Tests
|
96
|
+
|
97
|
+
You can run the test suite using:
|
98
|
+
|
99
|
+
```
|
100
|
+
$ ./bin/setup
|
101
|
+
$ rake
|
102
|
+
```
|
103
|
+
|
104
|
+
or try the project from the console with:
|
105
|
+
|
106
|
+
```
|
107
|
+
$ ./bin/console
|
108
|
+
```
|
109
|
+
|
110
|
+
### Linting
|
111
|
+
|
112
|
+
The project uses [standardrb](https://github.com/testdouble/standard) and can be run with:
|
113
|
+
|
114
|
+
```
|
115
|
+
$ ./bin/setup
|
116
|
+
$ rake standard # check
|
117
|
+
$ rake standard:fix # fix
|
118
|
+
```
|
95
119
|
|
96
120
|
## Contributing
|
97
121
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
-
|
2
|
-
require "rake/testtask"
|
1
|
+
begin
|
2
|
+
require "rake/testtask"
|
3
|
+
require "standard/rake"
|
3
4
|
|
4
|
-
Rake::TestTask.new(:test) do |t|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.libs << "lib"
|
8
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
9
|
+
end
|
10
|
+
|
11
|
+
task default: [:test, "standard:fix"]
|
9
12
|
|
10
|
-
|
13
|
+
desc "Run a simple benchmark (x1000)"
|
14
|
+
task :benchmark do
|
15
|
+
ruby "test/benchmark.rb"
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
# no standard/rspec available
|
19
|
+
end
|
data/lib/rqrcode_core.rb
CHANGED
data/lib/rqrcode_core/qrcode.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
3
|
+
require "rqrcode_core/qrcode/qr_8bit_byte"
|
4
|
+
require "rqrcode_core/qrcode/qr_alphanumeric"
|
5
|
+
require "rqrcode_core/qrcode/qr_bit_buffer"
|
6
|
+
require "rqrcode_core/qrcode/qr_code"
|
7
|
+
require "rqrcode_core/qrcode/qr_math"
|
8
|
+
require "rqrcode_core/qrcode/qr_numeric"
|
9
|
+
require "rqrcode_core/qrcode/qr_polynomial"
|
10
|
+
require "rqrcode_core/qrcode/qr_rs_block"
|
11
|
+
require "rqrcode_core/qrcode/qr_util"
|
@@ -2,21 +2,13 @@
|
|
2
2
|
|
3
3
|
module RQRCodeCore
|
4
4
|
class QR8bitByte
|
5
|
-
|
6
|
-
|
7
|
-
def initialize( data )
|
8
|
-
@mode = QRMODE[:mode_8bit_byte]
|
9
|
-
@data = data;
|
10
|
-
end
|
11
|
-
|
12
|
-
|
13
|
-
def get_length
|
14
|
-
@data.bytesize
|
5
|
+
def initialize(data)
|
6
|
+
@data = data
|
15
7
|
end
|
16
8
|
|
9
|
+
def write(buffer)
|
10
|
+
buffer.byte_encoding_start(@data.bytesize)
|
17
11
|
|
18
|
-
def write( buffer)
|
19
|
-
buffer.byte_encoding_start(get_length)
|
20
12
|
@data.each_byte do |b|
|
21
13
|
buffer.put(b, 8)
|
22
14
|
end
|
@@ -1,43 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RQRCodeCore
|
4
|
-
ALPHANUMERIC = [
|
4
|
+
ALPHANUMERIC = [
|
5
|
+
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
|
6
|
+
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "$",
|
7
|
+
"%", "*", "+", "-", ".", "/", ":"
|
8
|
+
].freeze
|
5
9
|
|
6
10
|
class QRAlphanumeric
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`" unless QRAlphanumeric.valid_data?(data)
|
13
|
-
|
14
|
-
@data = data;
|
15
|
-
end
|
16
|
-
|
11
|
+
def initialize(data)
|
12
|
+
unless QRAlphanumeric.valid_data?(data)
|
13
|
+
raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`"
|
14
|
+
end
|
17
15
|
|
18
|
-
|
19
|
-
@data.size
|
16
|
+
@data = data
|
20
17
|
end
|
21
18
|
|
22
|
-
def self.valid_data?
|
23
|
-
data.
|
24
|
-
return false if ALPHANUMERIC.index(s).nil?
|
25
|
-
end
|
26
|
-
true
|
19
|
+
def self.valid_data?(data)
|
20
|
+
(data.chars - ALPHANUMERIC).empty?
|
27
21
|
end
|
28
22
|
|
23
|
+
def write(buffer)
|
24
|
+
buffer.alphanumeric_encoding_start(@data.size)
|
29
25
|
|
30
|
-
|
31
|
-
buffer.alphanumeric_encoding_start(get_length)
|
32
|
-
|
33
|
-
(@data.size).times do |i|
|
26
|
+
@data.size.times do |i|
|
34
27
|
if i % 2 == 0
|
35
28
|
if i == (@data.size - 1)
|
36
29
|
value = ALPHANUMERIC.index(@data[i])
|
37
|
-
buffer.put(
|
30
|
+
buffer.put(value, 6)
|
38
31
|
else
|
39
|
-
value = (ALPHANUMERIC.index(@data[i]) * 45) + ALPHANUMERIC.index(@data[i+1])
|
40
|
-
buffer.put(
|
32
|
+
value = (ALPHANUMERIC.index(@data[i]) * 45) + ALPHANUMERIC.index(@data[i + 1])
|
33
|
+
buffer.put(value, 11)
|
41
34
|
end
|
42
35
|
end
|
43
36
|
end
|
@@ -13,74 +13,64 @@ module RQRCodeCore
|
|
13
13
|
@length = 0
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
def get( index )
|
16
|
+
def get(index)
|
18
17
|
buf_index = (index / 8).floor
|
19
|
-
((
|
18
|
+
((QRUtil.rszf(@buffer[buf_index], 7 - index % 8)) & 1) == 1
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
put_bit((((num).rszf(length - i - 1)) & 1) == 1)
|
21
|
+
def put(num, length)
|
22
|
+
(0...length).each do |i|
|
23
|
+
put_bit(((QRUtil.rszf(num, length - i - 1)) & 1) == 1)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
|
30
27
|
def get_length_in_bits
|
31
28
|
@length
|
32
29
|
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
buf_index = ( @length / 8 ).floor
|
31
|
+
def put_bit(bit)
|
32
|
+
buf_index = (@length / 8).floor
|
37
33
|
if @buffer.size <= buf_index
|
38
34
|
@buffer << 0
|
39
35
|
end
|
40
36
|
|
41
37
|
if bit
|
42
|
-
@buffer[buf_index] |=
|
38
|
+
@buffer[buf_index] |= QRUtil.rszf(0x80, @length % 8)
|
43
39
|
end
|
44
40
|
|
45
41
|
@length += 1
|
46
42
|
end
|
47
43
|
|
48
44
|
def byte_encoding_start(length)
|
49
|
-
|
50
|
-
put( QRMODE[:mode_8bit_byte], 4 )
|
45
|
+
put(QRMODE[:mode_8bit_byte], 4)
|
51
46
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_8bit_byte], @version))
|
52
|
-
|
53
47
|
end
|
54
48
|
|
55
49
|
def alphanumeric_encoding_start(length)
|
56
|
-
|
57
|
-
put( QRMODE[:mode_alpha_numk], 4 )
|
50
|
+
put(QRMODE[:mode_alpha_numk], 4)
|
58
51
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_alpha_numk], @version))
|
59
|
-
|
60
52
|
end
|
61
53
|
|
62
54
|
def numeric_encoding_start(length)
|
63
|
-
|
64
|
-
put( QRMODE[:mode_number], 4 )
|
55
|
+
put(QRMODE[:mode_number], 4)
|
65
56
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_number], @version))
|
66
|
-
|
67
57
|
end
|
68
58
|
|
69
59
|
def pad_until(prefered_size)
|
70
60
|
# Align on byte
|
71
61
|
while get_length_in_bits % 8 != 0
|
72
|
-
put_bit(
|
62
|
+
put_bit(false)
|
73
63
|
end
|
74
64
|
|
75
65
|
# Pad with padding code words
|
76
66
|
while get_length_in_bits < prefered_size
|
77
|
-
put(
|
78
|
-
put(
|
67
|
+
put(PAD0, 8)
|
68
|
+
put(PAD1, 8) if get_length_in_bits < prefered_size
|
79
69
|
end
|
80
70
|
end
|
81
71
|
|
82
72
|
def end_of_message(max_data_bits)
|
83
|
-
put(
|
73
|
+
put(0, 4) unless get_length_in_bits + 4 > max_data_bits
|
84
74
|
end
|
85
75
|
end
|
86
76
|
end
|