caesar-tax 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/allegedrc4.rb +48 -0
- data/lib/base64.rb +16 -0
- data/lib/caesar.rb +182 -0
- data/lib/qr_code.rb +4 -0
- data/lib/verhoeff.rb +45 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 45755c2bf8cf396c9b87b82ab70ce249f7eb964e9eb83a12e183a15bcc1a2134
|
4
|
+
data.tar.gz: 5311d28a7b21564eb57e1bdd64cf568637fc97505c40b72290f2446182dd230a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1f9c1cce860178be3ffa06e4345fb99bfc25446c026f023af4b933f221d21d1fdb4a1de995a4dfcd84787ef9f9fe5baba44936fe0d37ce29a28f2de38c4e8d80
|
7
|
+
data.tar.gz: 53408967ab9c155e6ced960734a7d5d13b17248efd5ed97199725fb3d5d69f54944aa37aab3cd97b5ce541c1d4d9a319297842cacc15c7dcde23bf71c6caed86
|
data/lib/allegedrc4.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AllegedRc4
|
4
|
+
# @param [String] message, key
|
5
|
+
# @param [String] key
|
6
|
+
# @return [String]
|
7
|
+
def self.to_alleged(message, key)
|
8
|
+
index1 = 0
|
9
|
+
index2 = 0
|
10
|
+
|
11
|
+
result = ''
|
12
|
+
state = []
|
13
|
+
(0..255).each do |i|
|
14
|
+
state.push i
|
15
|
+
end
|
16
|
+
|
17
|
+
(0..255).each do |i|
|
18
|
+
index2 = (key[index1].ord + state[i] + index2) % 256
|
19
|
+
state[i], state[index2] = swap_val(state[i], state[index2])
|
20
|
+
index1 = (index1 + 1) % key.length
|
21
|
+
end
|
22
|
+
|
23
|
+
x = 0
|
24
|
+
y = 0
|
25
|
+
(0..message.length - 1).each do |i|
|
26
|
+
x = (x + 1) % 256
|
27
|
+
y = (state[x] + y) % 256
|
28
|
+
state[x], state[y] = swap_val(state[x], state[y])
|
29
|
+
message_str = message[i].ord ^ state[(state[x] + state[y]) % 256]
|
30
|
+
result += '-' + fill_zero(message_str.to_s(16))
|
31
|
+
end
|
32
|
+
result[1, result.length - 1].upcase
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @param [String] val
|
38
|
+
# @return [String]
|
39
|
+
def self.fill_zero(val)
|
40
|
+
return "0#{val}" if val.length == 1
|
41
|
+
|
42
|
+
val
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.swap_val(value_for, value_to)
|
46
|
+
[value_to, value_for]
|
47
|
+
end
|
48
|
+
end
|
data/lib/base64.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Base64
|
2
|
+
@dict = %w(0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z + /)
|
3
|
+
|
4
|
+
# @param [Integer]
|
5
|
+
# @return [String]
|
6
|
+
def self.to_b64(number)
|
7
|
+
word = ''
|
8
|
+
while number > 0
|
9
|
+
number_part = number.to_i / 64
|
10
|
+
number_res = number % 64
|
11
|
+
word = @dict[number_res] + word
|
12
|
+
number = number_part
|
13
|
+
end
|
14
|
+
word
|
15
|
+
end
|
16
|
+
end
|
data/lib/caesar.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'allegedrc4'
|
5
|
+
require 'base64'
|
6
|
+
require 'verhoeff'
|
7
|
+
require 'qr_code'
|
8
|
+
|
9
|
+
class Caesar
|
10
|
+
def initialize
|
11
|
+
@seed = nil
|
12
|
+
@authorization_number = nil
|
13
|
+
@invoice_number = nil
|
14
|
+
@client_document = nil
|
15
|
+
@transaction_date = nil
|
16
|
+
@amount_total = nil
|
17
|
+
@control_code = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param [String] seed_str
|
21
|
+
# @return [Caesar]
|
22
|
+
def seed(seed_str)
|
23
|
+
@seed = seed_str
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [Integer] number
|
28
|
+
# @return [Caesar]
|
29
|
+
def authorization_number(number)
|
30
|
+
@authorization_number = number
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [Integer] number
|
35
|
+
# @return [Caesar]
|
36
|
+
def invoice_number(number)
|
37
|
+
@invoice_number = number
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [Integer] number
|
42
|
+
# @return [Caesar]
|
43
|
+
def client_document(number)
|
44
|
+
@client_document = number
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [DateTime]
|
49
|
+
# @return [Caesar]
|
50
|
+
# Set the format of date Date.strptime("2007-07-02", "%Y-%m-%d")
|
51
|
+
def transaction_date(date)
|
52
|
+
day = Time.new(date.year, date.month, date.day).strftime('%d')
|
53
|
+
month = Time.new(date.year, date.month, date.day).strftime('%m')
|
54
|
+
@transaction_date = "#{date.year}#{month}#{day}"
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param [Float] amount
|
59
|
+
# @return [Caesar]
|
60
|
+
def amount_total(amount)
|
61
|
+
raise ArgumentError 'Number cannot be 0 or less' if amount <= 0
|
62
|
+
|
63
|
+
@amount_total = amount.round
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String]
|
68
|
+
attr_reader :control_code
|
69
|
+
|
70
|
+
# @return [Caesar]
|
71
|
+
# This is the builder method for control code
|
72
|
+
def build_control_code
|
73
|
+
# Maybe can be a disaster, but this it the most legible way to do this.
|
74
|
+
control_exception
|
75
|
+
|
76
|
+
amount_total_vh, client_document_vh, invoice_number_vh, transaction_date_vh = calculate_verhoeff
|
77
|
+
amount_variables = [
|
78
|
+
invoice_number_vh.to_i,
|
79
|
+
client_document_vh.to_i,
|
80
|
+
transaction_date_vh.to_i,
|
81
|
+
amount_total_vh.to_i
|
82
|
+
].sum { |obj| obj }
|
83
|
+
|
84
|
+
amount_variables_vh_value = verhoeff(amount_variables, 5)
|
85
|
+
verhoeff_array = Verhoeff.plus_one(amount_variables_vh_value)
|
86
|
+
seed_array = split_seed(verhoeff_array)
|
87
|
+
|
88
|
+
authorization_number_vh = "#{@authorization_number}#{seed_array[0]}"
|
89
|
+
invoice_number_vh += seed_array[1]
|
90
|
+
client_document_vh += seed_array[2]
|
91
|
+
transaction_date_vh += seed_array[3]
|
92
|
+
amount_total_vh += seed_array[4]
|
93
|
+
|
94
|
+
message_str = authorization_number_vh + invoice_number_vh + client_document_vh + transaction_date_vh + amount_total_vh
|
95
|
+
key_cipher = "#{@seed}#{amount_variables_vh_value}"
|
96
|
+
message_alleged = AllegedRc4.to_alleged(message_str, key_cipher).delete('-')
|
97
|
+
fifth_ascii_total, first_ascii_total, fourth_ascii_total, second_ascii_total, third_ascii_total = calculate_ascii_total(message_alleged, verhoeff_array)
|
98
|
+
|
99
|
+
total_ascii_all = [first_ascii_total,
|
100
|
+
second_ascii_total,
|
101
|
+
third_ascii_total,
|
102
|
+
fourth_ascii_total,
|
103
|
+
fifth_ascii_total].sum { |obj| obj }
|
104
|
+
total_msg = Base64.to_b64(total_ascii_all)
|
105
|
+
@control_code = AllegedRc4.to_alleged(total_msg, key_cipher)
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# @param [String] message_alleged
|
112
|
+
# @param [String] verhoeff_array
|
113
|
+
# @return [Array<Integer>]
|
114
|
+
def calculate_ascii_total(message_alleged, verhoeff_array)
|
115
|
+
total_ascii_sum = ascii_sum(message_alleged)
|
116
|
+
first_ascii_total = (ascii_sum(message_alleged, 0, 5) * total_ascii_sum) / verhoeff_array[0]
|
117
|
+
second_ascii_total = (ascii_sum(message_alleged, 1, 5) * total_ascii_sum) / verhoeff_array[1]
|
118
|
+
third_ascii_total = (ascii_sum(message_alleged, 2, 5) * total_ascii_sum) / verhoeff_array[2]
|
119
|
+
fourth_ascii_total = (ascii_sum(message_alleged, 3, 5) * total_ascii_sum) / verhoeff_array[3]
|
120
|
+
fifth_ascii_total = (ascii_sum(message_alleged, 4, 5) * total_ascii_sum) / verhoeff_array[4]
|
121
|
+
[fifth_ascii_total, first_ascii_total, fourth_ascii_total, second_ascii_total, third_ascii_total]
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [Array<String>]
|
125
|
+
def calculate_verhoeff
|
126
|
+
invoice_number_vh = "#{@invoice_number}#{verhoeff(@invoice_number, 2)}"
|
127
|
+
client_document_vh = "#{@client_document}#{verhoeff(@client_document, 2)}"
|
128
|
+
transaction_date_vh = "#{@transaction_date}#{verhoeff(@transaction_date, 2)}"
|
129
|
+
amount_total_vh = "#{@amount_total}#{verhoeff(@amount_total, 2)}"
|
130
|
+
[amount_total_vh, client_document_vh, invoice_number_vh, transaction_date_vh]
|
131
|
+
end
|
132
|
+
|
133
|
+
def control_exception
|
134
|
+
control_exception_for(@seed)
|
135
|
+
control_exception_for(@authorization_number)
|
136
|
+
control_exception_for(@invoice_number)
|
137
|
+
control_exception_for(@client_document)
|
138
|
+
control_exception_for(@transaction_date)
|
139
|
+
control_exception_for(@amount_total)
|
140
|
+
end
|
141
|
+
|
142
|
+
# @param [String] message
|
143
|
+
# @param [Integer] initial_pos
|
144
|
+
# @param [Integer] increment
|
145
|
+
# @return [Integer]
|
146
|
+
def ascii_sum(message, initial_pos = 0, increment = 1)
|
147
|
+
sum = 0
|
148
|
+
while initial_pos < message.length
|
149
|
+
sum += message[initial_pos].ord
|
150
|
+
initial_pos += increment
|
151
|
+
end
|
152
|
+
sum
|
153
|
+
end
|
154
|
+
|
155
|
+
# @param [Array] verhoeff_array
|
156
|
+
# @return [Array]
|
157
|
+
def split_seed(verhoeff_array)
|
158
|
+
actual = 0
|
159
|
+
seed_array = []
|
160
|
+
verhoeff_array.length.times do |i|
|
161
|
+
seed_array.push(@seed[actual, verhoeff_array[i]])
|
162
|
+
actual += verhoeff_array[i]
|
163
|
+
end
|
164
|
+
seed_array
|
165
|
+
end
|
166
|
+
|
167
|
+
# @param [Integer] number
|
168
|
+
# @param [Integer] loop
|
169
|
+
def verhoeff(number, loop = 1)
|
170
|
+
vh_number = ''
|
171
|
+
loop.times do
|
172
|
+
vh_number += Verhoeff.to_verhoeff(number.to_s + vh_number).to_s
|
173
|
+
end
|
174
|
+
vh_number
|
175
|
+
end
|
176
|
+
|
177
|
+
# @param [Object] value
|
178
|
+
# @return [Exception]
|
179
|
+
def control_exception_for(value)
|
180
|
+
raise ArgumentError, "#{value.inspect} is Nil" if value.nil?
|
181
|
+
end
|
182
|
+
end
|
data/lib/qr_code.rb
ADDED
data/lib/verhoeff.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Verhoeff
|
2
|
+
@mult_matrix = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
3
|
+
[1, 2, 3, 4, 0, 6, 7, 8, 9, 5],
|
4
|
+
[2, 3, 4, 0, 1, 7, 8, 9, 5, 6],
|
5
|
+
[3, 4, 0, 1, 2, 8, 9, 5, 6, 7],
|
6
|
+
[4, 0, 1, 2, 3, 9, 5, 6, 7, 8],
|
7
|
+
[5, 9, 8, 7, 6, 0, 4, 3, 2, 1],
|
8
|
+
[6, 5, 9, 8, 7, 1, 0, 4, 3, 2],
|
9
|
+
[7, 6, 5, 9, 8, 2, 1, 0, 4, 3],
|
10
|
+
[8, 7, 6, 5, 9, 3, 2, 1, 0, 4],
|
11
|
+
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]]
|
12
|
+
@permutations_matrix = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
13
|
+
[1, 5, 7, 6, 2, 8, 3, 0, 9, 4],
|
14
|
+
[5, 8, 0, 3, 7, 9, 6, 1, 4, 2],
|
15
|
+
[8, 9, 1, 6, 0, 4, 3, 5, 2, 7],
|
16
|
+
[9, 4, 5, 3, 1, 2, 6, 8, 7, 0],
|
17
|
+
[4, 2, 8, 6, 5, 7, 3, 9, 0, 1],
|
18
|
+
[2, 7, 9, 3, 8, 0, 6, 4, 1, 5],
|
19
|
+
[7, 0, 4, 6, 9, 1, 3, 2, 5, 8]]
|
20
|
+
@numbers = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]
|
21
|
+
|
22
|
+
# @param [String] word
|
23
|
+
# @return [Integer]
|
24
|
+
def self.to_verhoeff(word)
|
25
|
+
check = 0
|
26
|
+
reverse_number = word.reverse
|
27
|
+
i = 0
|
28
|
+
while i <= (reverse_number.length - 1) do
|
29
|
+
check = @mult_matrix[check][@permutations_matrix[((i + 1) % 8)][reverse_number[i].to_i]]
|
30
|
+
i += 1
|
31
|
+
end
|
32
|
+
@numbers[check]
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param [String] message
|
36
|
+
# @return [Array]
|
37
|
+
def self.plus_one(message)
|
38
|
+
msg_array = message.split('')
|
39
|
+
msg_result = []
|
40
|
+
msg_array.each do |actual_msg|
|
41
|
+
msg_result.push(actual_msg.to_i + 1)
|
42
|
+
end
|
43
|
+
msg_result
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: caesar-tax
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Felix Daniel Coca Calvimontes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-20 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Much longer explanation of the example!
|
14
|
+
email: daniel.uremix@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/allegedrc4.rb
|
20
|
+
- lib/base64.rb
|
21
|
+
- lib/caesar.rb
|
22
|
+
- lib/qr_code.rb
|
23
|
+
- lib/verhoeff.rb
|
24
|
+
homepage: https://rubygems.org/gems/caesar-tax
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata:
|
28
|
+
source_code_uri: https://github.com/drkpkg/caesar-tax
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubygems_version: 3.0.3
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Gema para impuestos internos de Bolivia
|
48
|
+
test_files: []
|