amka 1.0.1 → 2.0.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 +5 -5
- data/CHANGELOG.md +28 -0
- data/CONTRIBUTING.md +84 -0
- data/README.md +42 -16
- data/USAGE.md +161 -0
- data/lib/amka/luhn.rb +96 -20
- data/lib/amka/utils.rb +150 -32
- data/lib/amka/version.rb +3 -1
- data/lib/amka.rb +99 -14
- metadata +19 -90
- data/.gitignore +0 -9
- data/.ruby-version +0 -1
- data/Gemfile +0 -4
- data/Rakefile +0 -8
- data/amka.gemspec +0 -28
- data/bin/console +0 -14
- data/bin/setup +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5f2628c4521fdb7fc9d1c9a09318e9189d837ede318ac1d19ac5fc606a1b9c24
|
4
|
+
data.tar.gz: da07a7a6bb486d1409f26a25969fc109ec392bac6b9e8c237a88fd6d0a816650
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56db96d08effcd378cb0c7f2bd7ae18041c2ce04c2d195152d94714e1fa750b67a1230467bd15b7871ec06dcd7632e96087dd7af3a55b44cbc4e248221a67754
|
7
|
+
data.tar.gz: a042775a314e742322c36c7769d07ffd152ce2893147226c64bafe12d6a4da6eaa281f931dcdc43cb22e3dc9fefa25b08e0dbd311f71a17179a769490a2938d7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,28 @@
|
|
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
|
+
## [2.0.0] - 2025-04-16
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
|
12
|
+
- Updated minimum Ruby version to 2.7.0
|
13
|
+
- Migrated from Minitest to RSpec for testing
|
14
|
+
- Modernized gem infrastructure
|
15
|
+
- Added GitHub Actions for CI
|
16
|
+
- Added SimpleCov for test coverage
|
17
|
+
- Improved documentation
|
18
|
+
|
19
|
+
### Security
|
20
|
+
|
21
|
+
- Added MFA requirement for gem publishing
|
22
|
+
- Updated development dependencies
|
23
|
+
|
24
|
+
## [1.0.1] - 2015-10-15
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- Initial release
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Contributing to AMKA
|
2
|
+
|
3
|
+
Thank you for considering contributing to the AMKA gem! This document outlines the process for contributing to this project.
|
4
|
+
|
5
|
+
## How Can I Contribute?
|
6
|
+
|
7
|
+
### Reporting Bugs
|
8
|
+
|
9
|
+
This section guides you through submitting a bug report. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
|
10
|
+
|
11
|
+
- **Use the GitHub issue tracker** — Check if the bug has already been reported by searching on GitHub under [Issues](https://github.com/ioagel/amka/issues).
|
12
|
+
- **Use the bug report template** — If you're reporting a bug, be sure to include all the information requested in the bug report template.
|
13
|
+
- **Provide specific examples** — Include specific steps to reproduce the problem, with example code if possible.
|
14
|
+
- **Describe the behavior you observed** — What happened? How did it differ from what you expected?
|
15
|
+
- **Include relevant details** — OS, Ruby version, AMKA gem version, etc.
|
16
|
+
|
17
|
+
### Suggesting Enhancements
|
18
|
+
|
19
|
+
This section guides you through submitting an enhancement suggestion, including completely new features and minor improvements to existing functionality.
|
20
|
+
|
21
|
+
- **Use the GitHub issue tracker** — Check if the enhancement has already been suggested by searching on GitHub under [Issues](https://github.com/ioagel/amka/issues).
|
22
|
+
- **Use the feature request template** — Include as much detail as possible in the template.
|
23
|
+
- **Provide a clear use case** — Explain why this enhancement would be useful to most AMKA users.
|
24
|
+
|
25
|
+
### Pull Requests
|
26
|
+
|
27
|
+
- **Fill in the required template**
|
28
|
+
- **Follow the Ruby style guide**
|
29
|
+
- **Include tests** — Your patch won't be accepted if it doesn't have tests.
|
30
|
+
- **Document your changes** — Update any relevant documentation.
|
31
|
+
- **Include updates to the CHANGELOG.md** file for any user-facing changes.
|
32
|
+
- **Create feature branches** — Don't ask us to pull from your main branch.
|
33
|
+
|
34
|
+
## Development Process
|
35
|
+
|
36
|
+
### Setting Up the Development Environment
|
37
|
+
|
38
|
+
1. Fork and clone the repository
|
39
|
+
2. Run `bin/setup` to install dependencies
|
40
|
+
3. Run `bundle exec rake spec` to run the tests
|
41
|
+
|
42
|
+
### Testing
|
43
|
+
|
44
|
+
- All tests must pass before a pull request will be accepted
|
45
|
+
- Write tests for all new functionality
|
46
|
+
- Run tests using `bundle exec rake spec`
|
47
|
+
- Check code coverage (we aim for >90%) using `open coverage/index.html` after running tests
|
48
|
+
|
49
|
+
### Style Guidelines
|
50
|
+
|
51
|
+
- Follow the Ruby style guide:
|
52
|
+
- Use 2 spaces for indentation
|
53
|
+
- Use snake_case for methods and variables
|
54
|
+
- Use CamelCase for classes and modules
|
55
|
+
- Add descriptive comments for public methods and classes
|
56
|
+
- Run `bundle exec rubocop` before submitting to ensure code quality
|
57
|
+
- Add YARD documentation for new public methods
|
58
|
+
|
59
|
+
### Git Commit Messages
|
60
|
+
|
61
|
+
- Use the present tense ("Add feature" not "Added feature")
|
62
|
+
- Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
63
|
+
- Limit the first line to 72 characters or less
|
64
|
+
- Reference issues and pull requests after the first line
|
65
|
+
|
66
|
+
## Releasing a New Version
|
67
|
+
|
68
|
+
For maintainers only:
|
69
|
+
|
70
|
+
1. Update the version number in `lib/amka/version.rb`
|
71
|
+
2. Update the CHANGELOG.md
|
72
|
+
3. Run the test suite to make sure everything works
|
73
|
+
4. Commit changes with message "Bump version to x.y.z"
|
74
|
+
5. Tag the commit with "vx.y.z"
|
75
|
+
6. Push to GitHub
|
76
|
+
7. Run `bundle exec rake release`
|
77
|
+
|
78
|
+
## Additional Resources
|
79
|
+
|
80
|
+
- [General GitHub documentation](https://help.github.com)
|
81
|
+
- [GitHub pull request documentation](https://help.github.com/articles/about-pull-requests/)
|
82
|
+
- [Ruby style guide](https://github.com/rubocop/ruby-style-guide)
|
83
|
+
|
84
|
+
Thank you for contributing!
|
data/README.md
CHANGED
@@ -1,23 +1,37 @@
|
|
1
1
|
# AMKA and Luhn IDs Validator / Generator
|
2
|
-
|
2
|
+
|
3
|
+
[](https://github.com/ioagel/amka/actions/workflows/ci.yml)
|
4
|
+
[](https://badge.fury.io/rb/amka)
|
5
|
+
[](http://rubydoc.info/gems/amka)
|
6
|
+
|
7
|
+
## Α.Μ.Κ.Α (Αριθμός Μητρώου Κοινωνικής Ασφάλισης)
|
8
|
+
|
3
9
|
This gem validates **A.M.K.A** Greek social security IDs by
|
4
10
|
using the Luhn algorithm, as described in this [Wikipedia article](https://en.wikipedia.org/wiki/Luhn_algorithm).
|
5
11
|
The only additional validation needed that applies to Greek A.M.K.A is that the
|
6
12
|
first 6 digits must be a valid date (date of birth).
|
7
13
|
|
8
|
-
The gem also
|
9
|
-
**AMKA** (like) ids. The
|
14
|
+
The gem also _validates_ and _generates_ **Luhn** ids, as well as _generating_
|
15
|
+
**AMKA** (like) ids. The _like_ here means that the AMKA generated are not
|
10
16
|
**real** as those provided by the Official Authorities in Greece.
|
11
17
|
|
12
18
|
There is an online calculator in [planetcalc](http://planetcalc.com/2464/), you
|
13
19
|
can validate the results of the gem, until you are confident that is working
|
14
20
|
as it should. Try you own and your family AMKA.
|
15
21
|
|
16
|
-
**DISCLAIMER**: The gem
|
22
|
+
**DISCLAIMER**: The gem _does not_ validate the real existence of the A.M.K.A or that it
|
17
23
|
belongs to a given person. The same applies to the generator.
|
18
24
|
|
25
|
+
## Documentation
|
26
|
+
|
27
|
+
- [Usage Guide](USAGE.md) - Comprehensive examples and use cases
|
28
|
+
- [API Documentation](http://rubydoc.info/gems/amka) - Full method documentation
|
29
|
+
- [Contributing Guide](CONTRIBUTING.md) - How to contribute to this gem
|
30
|
+
- [Changelog](CHANGELOG.md) - Version history and changes
|
31
|
+
|
19
32
|
## Installation
|
20
|
-
|
33
|
+
|
34
|
+
Requires ruby >= 2.7.0
|
21
35
|
|
22
36
|
Add this line to your application's Gemfile:
|
23
37
|
|
@@ -27,13 +41,17 @@ gem 'amka'
|
|
27
41
|
|
28
42
|
And then execute:
|
29
43
|
|
30
|
-
|
44
|
+
```bash
|
45
|
+
bundle install
|
46
|
+
```
|
31
47
|
|
32
48
|
Or install it yourself as:
|
33
49
|
|
34
|
-
|
50
|
+
```bash
|
51
|
+
gem install amka
|
52
|
+
```
|
35
53
|
|
36
|
-
##
|
54
|
+
## Quick Start
|
37
55
|
|
38
56
|
```ruby
|
39
57
|
require 'amka'
|
@@ -43,6 +61,10 @@ Amka.valid?('01011441432')
|
|
43
61
|
# returns false (i did not use a valid one in this example just in case
|
44
62
|
# it belonged to a real person!!!!)
|
45
63
|
|
64
|
+
# You can also pass the 4 digit year of birth as a second string argument
|
65
|
+
# This will increase the accuracy of the date part of validation to 100%.
|
66
|
+
Amka.valid?('111098xxxxx', '1998')
|
67
|
+
|
46
68
|
# To generate (returns the AMKA as a string)
|
47
69
|
Amka.generate
|
48
70
|
|
@@ -58,24 +80,28 @@ Amka::Luhn.valid?('1142376755673') # returns true
|
|
58
80
|
# To generate a Luhn id
|
59
81
|
# takes up to 2 arguments: total, id_start(optional)
|
60
82
|
# total: how many digits you want in the Luhn generated
|
61
|
-
# id_start: string of numbers to include
|
62
|
-
# - total must be greater than id_start by at least one, to
|
63
|
-
#
|
83
|
+
# id_start: string of numbers to include at the start of the Luhn
|
84
|
+
# - total must be greater than the length of id_start by at least one, to
|
85
|
+
# account for the rightmost check digit.
|
64
86
|
Amka::Luhn.generate(13) # returns '5361281695669'
|
65
87
|
Amka::Luhn.generate(10, '123456789') # returns '1234567897', 7 is the check digit.
|
66
88
|
Amka::Luhn.generate(15, '12345') # returns something like: '123450789968798'
|
67
89
|
```
|
68
90
|
|
69
|
-
|
91
|
+
See the [Usage Guide](USAGE.md) for more detailed examples and advanced usage.
|
70
92
|
|
71
|
-
|
93
|
+
## Development
|
94
|
+
|
95
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
96
|
+
|
97
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
72
98
|
|
73
99
|
## Contributing
|
74
100
|
|
75
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/ioagel/amka
|
101
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/ioagel/amka>.
|
76
102
|
|
103
|
+
Please see the [Contributing Guide](CONTRIBUTING.md) for more details on how to contribute.
|
77
104
|
|
78
105
|
## License
|
79
106
|
|
80
|
-
The gem is available as open source under the terms of the [MIT License](
|
81
|
-
|
107
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/USAGE.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# AMKA Gem Usage Guide
|
2
|
+
|
3
|
+
This document provides comprehensive examples and guidelines for using the AMKA gem in your Ruby projects.
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
- [AMKA Gem Usage Guide](#amka-gem-usage-guide)
|
8
|
+
- [Table of Contents](#table-of-contents)
|
9
|
+
- [Understanding AMKA](#understanding-amka)
|
10
|
+
- [Basic Usage](#basic-usage)
|
11
|
+
- [Installation](#installation)
|
12
|
+
- [Validation](#validation)
|
13
|
+
- [Generation](#generation)
|
14
|
+
- [Advanced Usage](#advanced-usage)
|
15
|
+
- [Working with Birth Dates](#working-with-birth-dates)
|
16
|
+
- [Using the Luhn Algorithm Directly](#using-the-luhn-algorithm-directly)
|
17
|
+
- [Error Handling](#error-handling)
|
18
|
+
- [Performance Considerations](#performance-considerations)
|
19
|
+
- [Use Cases](#use-cases)
|
20
|
+
|
21
|
+
## Understanding AMKA
|
22
|
+
|
23
|
+
An AMKA (Αριθμός Μητρώου Κοινωνικής Ασφάλισης) is a unique 11-digit identification number used in Greece. It's similar to a Social Security Number in the United States and follows these rules:
|
24
|
+
|
25
|
+
1. It's always exactly 11 digits long
|
26
|
+
2. The first 6 digits represent the person's date of birth in format DDMMYY
|
27
|
+
3. The number (as a whole) must pass validation by the Luhn algorithm
|
28
|
+
4. The last digit is a check digit computed using the Luhn algorithm
|
29
|
+
|
30
|
+
## Basic Usage
|
31
|
+
|
32
|
+
### Installation
|
33
|
+
|
34
|
+
Add the gem to your Gemfile:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gem 'amka'
|
38
|
+
```
|
39
|
+
|
40
|
+
Or install it directly:
|
41
|
+
|
42
|
+
```bash
|
43
|
+
gem install amka
|
44
|
+
```
|
45
|
+
|
46
|
+
Then require it in your code:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'amka'
|
50
|
+
```
|
51
|
+
|
52
|
+
### Validation
|
53
|
+
|
54
|
+
You can validate an AMKA number with a simple call:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# Basic validation
|
58
|
+
Amka.valid?('01019012345') # => true or false
|
59
|
+
|
60
|
+
# The validation checks:
|
61
|
+
# 1. If it's exactly 11 digits
|
62
|
+
# 2. If the first 6 digits form a valid date (ddmmyy)
|
63
|
+
# 3. If the number passes the Luhn algorithm check
|
64
|
+
```
|
65
|
+
|
66
|
+
When working with dates from different centuries, you can provide the 4-digit year for more accurate validation:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
# Explicitly specify century for validation
|
70
|
+
Amka.valid?('01019012345', '1990') # => true
|
71
|
+
Amka.valid?('01019012345', '2090') # => false (if the year doesn't match)
|
72
|
+
```
|
73
|
+
|
74
|
+
### Generation
|
75
|
+
|
76
|
+
You can generate random valid AMKA numbers:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
# Generate a random valid AMKA
|
80
|
+
amka = Amka.generate # => "01019012345"
|
81
|
+
```
|
82
|
+
|
83
|
+
Or generate an AMKA with a specific birth date:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# Generate an AMKA for someone born January 1, 1990
|
87
|
+
amka = Amka.generate('1/1/1990') # => "01019012345"
|
88
|
+
|
89
|
+
# Days and months can be 1 or 2 digits
|
90
|
+
amka = Amka.generate('15/12/1985') # => "15128512345"
|
91
|
+
```
|
92
|
+
|
93
|
+
## Advanced Usage
|
94
|
+
|
95
|
+
### Working with Birth Dates
|
96
|
+
|
97
|
+
The first 6 digits of an AMKA represent a date of birth in DDMMYY format:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
amka = '01019012345'
|
101
|
+
birth_date = Date.strptime(amka[0..5], '%d%m%y') # => #<Date: 1990-01-01>
|
102
|
+
|
103
|
+
# For ambiguous 2-digit years, you might need to adjust the century
|
104
|
+
if birth_date > Date.today
|
105
|
+
birth_date = Date.strptime(amka[0..3] + '19' + amka[4..5], '%d%m%Y')
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
### Using the Luhn Algorithm Directly
|
110
|
+
|
111
|
+
The gem includes a standalone implementation of the Luhn algorithm that can be used for other purposes:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# Validate any number against the Luhn algorithm
|
115
|
+
Amka::Luhn.valid?('4532015112830366') # => true (valid credit card number)
|
116
|
+
Amka::Luhn.valid?('1234567890') # => false
|
117
|
+
|
118
|
+
# Generate a valid Luhn number of specific length
|
119
|
+
luhn_id = Amka::Luhn.generate(16) # => "4532015112830366"
|
120
|
+
|
121
|
+
# Generate a valid Luhn number with a specific prefix
|
122
|
+
luhn_id = Amka::Luhn.generate(16, '4532') # => "4532015112830366"
|
123
|
+
```
|
124
|
+
|
125
|
+
## Error Handling
|
126
|
+
|
127
|
+
The gem will raise descriptive `ArgumentError` exceptions for invalid inputs:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
begin
|
131
|
+
Amka.valid?(12345) # Not a string
|
132
|
+
rescue ArgumentError => e
|
133
|
+
puts e.message # => "'12345': must be a string of digits only!"
|
134
|
+
end
|
135
|
+
|
136
|
+
begin
|
137
|
+
Amka.generate('invalid-date')
|
138
|
+
rescue ArgumentError => e
|
139
|
+
puts e.message # => "date of birth must be in this format: [d]d/[m]m/yyyy"
|
140
|
+
end
|
141
|
+
|
142
|
+
begin
|
143
|
+
Amka.generate('31/2/1990') # February 31st doesn't exist
|
144
|
+
rescue ArgumentError => e
|
145
|
+
puts e.message # => "The date of birth is invalid!"
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
## Performance Considerations
|
150
|
+
|
151
|
+
- The validation and generation methods are lightweight and suitable for high-volume use
|
152
|
+
- No external dependencies are required
|
153
|
+
- All operations are performed in memory without any I/O
|
154
|
+
|
155
|
+
## Use Cases
|
156
|
+
|
157
|
+
- Government systems that need to validate AMKA numbers
|
158
|
+
- Healthcare applications that need to work with patient identification
|
159
|
+
- Testing systems that need to generate sample data
|
160
|
+
- Any application that needs to implement the Luhn algorithm validation
|
161
|
+
- Form validation for Greek websites
|
data/lib/amka/luhn.rb
CHANGED
@@ -1,40 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Amka
|
2
4
|
# Implements the Luhn algorithm as described in the wikipedia article
|
3
5
|
# https://en.wikipedia.org/wiki/Luhn_algorithm
|
6
|
+
#
|
7
|
+
# The Luhn algorithm (also known as the "modulus 10" or "mod 10" algorithm)
|
8
|
+
# is a simple checksum formula used to validate various identification numbers,
|
9
|
+
# such as credit card numbers, IMEI numbers, and national identification numbers
|
10
|
+
# (like AMKA in Greece).
|
11
|
+
#
|
12
|
+
# ## Algorithm Steps
|
13
|
+
# 1. Starting from the rightmost digit, double the value of every second digit
|
14
|
+
# 2. If doubling a number results in a two-digit number (>9), subtract 9 from the result
|
15
|
+
# 3. Sum all digits (both doubled and non-doubled)
|
16
|
+
# 4. If the total modulo 10 is 0, then the number is valid
|
17
|
+
#
|
18
|
+
# ## Uses
|
19
|
+
# This class provides both validation of existing IDs and generation of
|
20
|
+
# new valid IDs that follow the Luhn algorithm.
|
21
|
+
#
|
22
|
+
# @example Validate a Luhn ID
|
23
|
+
# Amka::Luhn.valid?('79927398713') #=> true
|
24
|
+
#
|
25
|
+
# @example Generate a new Luhn ID of specified length
|
26
|
+
# Amka::Luhn.generate(10) #=> "7992739871"
|
27
|
+
#
|
28
|
+
# @example Generate a Luhn ID with a specific prefix
|
29
|
+
# Amka::Luhn.generate(16, '4532') #=> "4532015112830366"
|
4
30
|
class Luhn
|
5
|
-
|
31
|
+
# Validates if a given ID follows the Luhn algorithm
|
32
|
+
#
|
33
|
+
# Applies the standard Luhn algorithm to check if a number is valid:
|
34
|
+
# 1. From the rightmost digit, double every second digit
|
35
|
+
# 2. Sum the digits (if any doubled digit > 9, subtract 9)
|
36
|
+
# 3. If the sum is divisible by 10, the number is valid
|
37
|
+
#
|
38
|
+
# @param luhn_id [String] the ID to validate, must be a string containing only digits
|
39
|
+
# @return [Boolean] true if valid according to Luhn algorithm, false otherwise
|
40
|
+
# @raise [ArgumentError] if the ID is not a string of digits
|
41
|
+
# @example Validating a credit card number
|
42
|
+
# Amka::Luhn.valid?('4532015112830366') #=> true
|
43
|
+
# @example Validating an invalid number
|
44
|
+
# Amka::Luhn.valid?('1234567890') #=> false
|
6
45
|
def self.valid?(luhn_id)
|
7
|
-
Utils.string_with_digits_or_fail
|
46
|
+
Utils.string_with_digits_or_fail(luhn_id)
|
8
47
|
|
9
48
|
digits_sum = calculate_digits_sum(luhn_id)
|
10
49
|
|
11
|
-
(digits_sum % 10)
|
50
|
+
(digits_sum % 10).zero?
|
12
51
|
end
|
13
52
|
|
53
|
+
# Generates a valid Luhn ID
|
54
|
+
#
|
55
|
+
# Creates a number that passes the Luhn check by:
|
56
|
+
# 1. Taking the provided prefix (or creating a random one)
|
57
|
+
# 2. Calculating what the check digit should be for the number to be valid
|
58
|
+
# 3. Appending the check digit to create a valid Luhn number
|
59
|
+
#
|
60
|
+
# @param total [Integer] the total length of the ID to generate
|
61
|
+
# @param id_start [String] optional digits to use at the start of the ID
|
62
|
+
# @return [String] a valid Luhn ID of exactly 'total' length
|
63
|
+
# @raise [ArgumentError] if arguments are invalid
|
64
|
+
# @example Generate a 16-digit number (like a credit card)
|
65
|
+
# Amka::Luhn.generate(16) #=> "4532015112830366"
|
66
|
+
# @example Generate a number with a specific prefix
|
67
|
+
# Amka::Luhn.generate(10, '123456') #=> "1234567897"
|
68
|
+
# @example Special case for length 1
|
69
|
+
# Amka::Luhn.generate(1) #=> "0"
|
14
70
|
def self.generate(total, id_start = '')
|
15
71
|
validate_generate_args_or_fail(total, id_start)
|
16
|
-
|
72
|
+
return '0' if id_start.empty? && total == 1
|
17
73
|
|
18
74
|
last_digits_length = total - id_start.length
|
19
|
-
|
75
|
+
# Use String.new to create an unfrozen string
|
76
|
+
last_digits_except_check = String.new
|
20
77
|
# subtract by one to account for the check digit
|
21
78
|
(last_digits_length - 1).times { last_digits_except_check << rand(0..9).to_s }
|
22
|
-
|
79
|
+
# Using + instead of << for string concatenation to prevent frozen string issues
|
80
|
+
luhn_id_except_check_digit = id_start + last_digits_except_check
|
23
81
|
|
24
|
-
digits_sum = calculate_digits_sum(luhn_id_except_check_digit, true)
|
82
|
+
digits_sum = calculate_digits_sum(luhn_id_except_check_digit, generate: true)
|
25
83
|
|
26
84
|
check_digit = (digits_sum * 9) % 10
|
27
85
|
|
28
|
-
luhn_id_except_check_digit
|
86
|
+
luhn_id_except_check_digit + check_digit.to_s
|
29
87
|
end
|
30
88
|
|
31
|
-
|
89
|
+
# Calculates the sum of digits according to the Luhn algorithm
|
90
|
+
#
|
91
|
+
# This implementation handles both validation of existing numbers and
|
92
|
+
# generation of new numbers with the 'generate' parameter determining the pattern
|
93
|
+
# of which digits to double.
|
94
|
+
#
|
95
|
+
# @param luhn_id [String] the ID to calculate the sum for
|
96
|
+
# @param generate [Boolean] whether we're generating (affects digit doubling pattern)
|
97
|
+
# @return [Integer] the sum of digits according to Luhn algorithm rules
|
98
|
+
def self.calculate_digits_sum(luhn_id, generate: false)
|
32
99
|
luhn_id_double = luhn_id.chars.reverse.map(&:to_i).map.with_index do |digit, i|
|
33
|
-
if (!generate && i.odd?) || (generate && i.even?)
|
34
|
-
|
35
|
-
|
36
|
-
digit -= 9
|
37
|
-
end
|
100
|
+
if ((!generate && i.odd?) || (generate && i.even?)) && ((digit *= 2) > 9)
|
101
|
+
# Same as: digit = digit.to_s.chars.map(&:to_i).reduce(:+)
|
102
|
+
digit -= 9
|
38
103
|
end
|
39
104
|
digit
|
40
105
|
end
|
@@ -42,14 +107,25 @@ module Amka
|
|
42
107
|
end
|
43
108
|
private_class_method :calculate_digits_sum
|
44
109
|
|
110
|
+
# Validates the arguments for the generate method
|
111
|
+
#
|
112
|
+
# Performs several checks:
|
113
|
+
# 1. Ensures id_start is a string containing only digits (or empty)
|
114
|
+
# 2. Ensures total is a positive integer
|
115
|
+
# 3. Ensures total > id_start.length to allow room for the check digit
|
116
|
+
#
|
117
|
+
# @param total [Integer] the total length of the ID to generate
|
118
|
+
# @param id_start [String] digits to use at the start of the ID
|
119
|
+
# @raise [ArgumentError] if arguments are invalid
|
45
120
|
def self.validate_generate_args_or_fail(total, id_start)
|
46
|
-
Utils.string_with_digits_or_empty_or_fail
|
47
|
-
Utils.positive_integer_or_fail
|
48
|
-
|
49
|
-
|
50
|
-
|
121
|
+
Utils.string_with_digits_or_empty_or_fail(id_start)
|
122
|
+
Utils.positive_integer_or_fail(total)
|
123
|
+
|
124
|
+
return if total > id_start.length
|
125
|
+
|
126
|
+
raise ArgumentError, "'#{total}': must be greater at least by one from string length: " \
|
127
|
+
"#{id_start.length}, to account for the check digit!"
|
51
128
|
end
|
52
129
|
private_class_method :validate_generate_args_or_fail
|
53
|
-
|
54
130
|
end
|
55
131
|
end
|
data/lib/amka/utils.rb
CHANGED
@@ -1,57 +1,175 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Amka
|
4
|
+
# Utility methods for the Amka module
|
5
|
+
#
|
6
|
+
# This class provides helper methods for parameter validation and date handling
|
7
|
+
# that are used throughout the AMKA implementation. These utilities encapsulate
|
8
|
+
# common validation logic and error handling to keep the main code cleaner.
|
9
|
+
#
|
10
|
+
# The methods primarily fall into these categories:
|
11
|
+
# - String validation (digits only, format checking)
|
12
|
+
# - Number validation
|
13
|
+
# - Date validation and conversion
|
14
|
+
#
|
15
|
+
# All validation methods follow a consistent pattern: they either succeed silently
|
16
|
+
# or raise descriptive ArgumentError exceptions.
|
3
17
|
class Utils
|
4
18
|
class << self
|
19
|
+
# Validates that the input is a string with only digits
|
20
|
+
#
|
21
|
+
# Used when a value must be a non-empty string of digits, such as
|
22
|
+
# an ID or number that needs to be processed digit by digit.
|
23
|
+
#
|
24
|
+
# @param id [String] the string to validate
|
25
|
+
# @raise [ArgumentError] if the string is not all digits
|
26
|
+
# @example
|
27
|
+
# Utils.string_with_digits_or_fail('12345') # => nil (success)
|
28
|
+
# Utils.string_with_digits_or_fail('123abc') # => ArgumentError
|
29
|
+
# Utils.string_with_digits_or_fail('') # => ArgumentError
|
5
30
|
def string_with_digits_or_fail(id)
|
6
|
-
id.is_a?(String) && id.match(/\A\d+\Z/)
|
7
|
-
|
31
|
+
return if id.is_a?(String) && id.match(/\A\d+\Z/)
|
32
|
+
|
33
|
+
raise ArgumentError, "'#{id}': must be a string of digits only!"
|
8
34
|
end
|
9
35
|
|
36
|
+
# Validates that the input is a string with only digits or empty
|
37
|
+
#
|
38
|
+
# Similar to string_with_digits_or_fail but allows empty strings.
|
39
|
+
# Used when an optional string of digits is expected.
|
40
|
+
#
|
41
|
+
# @param id [String] the string to validate
|
42
|
+
# @raise [ArgumentError] if the string contains non-digits
|
43
|
+
# @example
|
44
|
+
# Utils.string_with_digits_or_empty_or_fail('12345') # => nil (success)
|
45
|
+
# Utils.string_with_digits_or_empty_or_fail('') # => nil (success)
|
46
|
+
# Utils.string_with_digits_or_empty_or_fail('123abc') # => ArgumentError
|
10
47
|
def string_with_digits_or_empty_or_fail(id)
|
11
|
-
id.is_a?(String) && id.match(/\A\d*\Z/)
|
12
|
-
|
48
|
+
return if id.is_a?(String) && id.match(/\A\d*\Z/)
|
49
|
+
|
50
|
+
raise ArgumentError, "'#{id}': must be a string of digits or even an empty one!"
|
13
51
|
end
|
14
52
|
|
53
|
+
# Validates that the input is a string with date in format dd/mm/yyyy
|
54
|
+
#
|
55
|
+
# Checks that the string follows the Greek date format where:
|
56
|
+
# - Day can be 1 or 2 digits (1-31)
|
57
|
+
# - Month can be 1 or 2 digits (1-12)
|
58
|
+
# - Year must be 4 digits
|
59
|
+
#
|
60
|
+
# Note: This only checks the format, not if the date is valid
|
61
|
+
# (e.g., 31/02/2022 would pass this check but is not a valid date)
|
62
|
+
#
|
63
|
+
# @param date [String] the date string to validate
|
64
|
+
# @raise [ArgumentError] if the date format is invalid
|
65
|
+
# @example
|
66
|
+
# Utils.string_with_date_or_fail('1/1/2020') # => nil (success)
|
67
|
+
# Utils.string_with_date_or_fail('31/12/2020') # => nil (success)
|
68
|
+
# Utils.string_with_date_or_fail('2020-12-31') # => ArgumentError
|
15
69
|
def string_with_date_or_fail(date)
|
16
|
-
date.is_a?(String) && date.match(%r{\A\d?\d{1}/\d?\d{1}/\d{4}\Z})
|
17
|
-
|
70
|
+
return if date.is_a?(String) && date.match(%r{\A\d?\d{1}/\d?\d{1}/\d{4}\Z})
|
71
|
+
|
72
|
+
raise ArgumentError, 'date of birth must be in this format: [d]d/[m]m/yyyy'
|
18
73
|
end
|
19
74
|
|
75
|
+
# Validates that the input is a positive integer
|
76
|
+
#
|
77
|
+
# Used primarily for length/count parameters where negative or
|
78
|
+
# zero values would be invalid.
|
79
|
+
#
|
80
|
+
# @param num [Integer] the number to validate
|
81
|
+
# @raise [ArgumentError] if the number is not a positive integer
|
82
|
+
# @example
|
83
|
+
# Utils.positive_integer_or_fail(10) # => nil (success)
|
84
|
+
# Utils.positive_integer_or_fail(0) # => ArgumentError
|
85
|
+
# Utils.positive_integer_or_fail(-5) # => ArgumentError
|
86
|
+
# Utils.positive_integer_or_fail('5') # => ArgumentError
|
20
87
|
def positive_integer_or_fail(num)
|
21
|
-
num.is_a?(Integer) && num
|
22
|
-
|
88
|
+
return if num.is_a?(Integer) && num.positive?
|
89
|
+
|
90
|
+
raise ArgumentError, "'#{num}': must be a non-zero positive integer!"
|
23
91
|
end
|
24
92
|
|
93
|
+
# Validates that the given date string is a valid date
|
94
|
+
#
|
95
|
+
# This is a more comprehensive date validation that:
|
96
|
+
# 1. Checks the basic format
|
97
|
+
# 2. Confirms the date actually exists in the calendar
|
98
|
+
# 3. Optionally verifies it matches a specific 4-digit year
|
99
|
+
#
|
100
|
+
# This is particularly important for AMKA validation since the
|
101
|
+
# first 6 digits must represent a valid date of birth.
|
102
|
+
#
|
103
|
+
# @param date [String] the date string to validate in format ddmmyy
|
104
|
+
# @param year [String, nil] optional 4-digit year to check against
|
105
|
+
# @return [Boolean] true if date is valid, false otherwise
|
106
|
+
# @raise [ArgumentError] if year format or range is invalid
|
107
|
+
# @example Simple validation (auto-guesses century)
|
108
|
+
# Utils.valid_date?('010190') # => true (January 1, 1990)
|
109
|
+
# @example With explicit year
|
110
|
+
# Utils.valid_date?('010190', '1990') # => true
|
111
|
+
# Utils.valid_date?('010190', '2090') # => ArgumentError
|
25
112
|
def valid_date?(date, year = nil)
|
26
113
|
return false unless date.match(/\A\d{6,}\Z/)
|
27
114
|
|
28
|
-
|
29
|
-
year
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
115
|
+
if year
|
116
|
+
validate_year_format(year, date)
|
117
|
+
return validate_full_date(date, year)
|
118
|
+
end
|
119
|
+
|
120
|
+
validate_short_date(date)
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# Validates the year format and range
|
126
|
+
#
|
127
|
+
# @param year [String] the 4-digit year to validate
|
128
|
+
# @param date [String] the date string (for year digit comparison)
|
129
|
+
# @raise [ArgumentError] if year format or range is invalid
|
130
|
+
def validate_year_format(year, date)
|
131
|
+
unless year.is_a?(String) && year.match(/\A\d{4}\Z/)
|
132
|
+
raise ArgumentError, 'Year must be a 4 digit string'
|
42
133
|
end
|
43
134
|
|
44
|
-
|
45
|
-
|
46
|
-
if date_2_digit_year > Date.today
|
47
|
-
Date.strptime(date[0..3] << '19' << date[4..5], '%d%m%Y')
|
48
|
-
end
|
49
|
-
return true
|
50
|
-
rescue ArgumentError
|
51
|
-
return false
|
135
|
+
unless year.to_i.between?(1800, Date.today.year)
|
136
|
+
raise ArgumentError, 'Year must be between 1800 and current!'
|
52
137
|
end
|
138
|
+
|
139
|
+
return if year[2..3] == date[4..5]
|
140
|
+
|
141
|
+
raise ArgumentError, 'The last 2 digits of year parameter and the 2 digits ' \
|
142
|
+
'that correspond to the year in date must be equal!'
|
143
|
+
end
|
144
|
+
|
145
|
+
# Validates a date with a full 4-digit year
|
146
|
+
#
|
147
|
+
# Checks if the given date in DDMMYYYY format is valid and in the past.
|
148
|
+
#
|
149
|
+
# @param date [String] the date string (first 6 digits, format ddmmyy)
|
150
|
+
# @param year [String] the 4-digit year
|
151
|
+
# @return [Boolean] true if date is valid and in the past
|
152
|
+
def validate_full_date(date, year)
|
153
|
+
dob = Date.strptime(date[0..3] << year, '%d%m%Y')
|
154
|
+
dob < Date.today
|
155
|
+
rescue ArgumentError
|
156
|
+
false
|
157
|
+
end
|
158
|
+
|
159
|
+
# Validates a date with just 2-digit year
|
160
|
+
#
|
161
|
+
# Handles the ambiguity of 2-digit years by trying to interpret
|
162
|
+
# them as 20xx or 19xx years based on what makes sense.
|
163
|
+
#
|
164
|
+
# @param date [String] the date string (first 6 digits, format ddmmyy)
|
165
|
+
# @return [Boolean] true if date is valid
|
166
|
+
def validate_short_date(date)
|
167
|
+
date_2_digit_year = Date.strptime(date[0..5], '%d%m%y')
|
168
|
+
Date.strptime(date[0..3] << '19' << date[4..5], '%d%m%Y') if date_2_digit_year > Date.today
|
169
|
+
true
|
170
|
+
rescue ArgumentError
|
171
|
+
false
|
53
172
|
end
|
54
173
|
end
|
55
174
|
end
|
56
|
-
|
57
175
|
end
|
data/lib/amka/version.rb
CHANGED
data/lib/amka.rb
CHANGED
@@ -1,10 +1,54 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'amka/version'
|
2
4
|
require 'date'
|
3
5
|
|
6
|
+
# The Amka module provides functionality for validating and generating
|
7
|
+
# Greek A.M.K.A (social security) IDs as well as generic Luhn algorithm IDs.
|
8
|
+
# A.M.K.A IDs follow the Luhn algorithm and have their first 6 digits
|
9
|
+
# representing the date of birth in format DDMMYY.
|
10
|
+
#
|
11
|
+
# An AMKA (Αριθμός Μητρώου Κοινωνικής Ασφάλισης) is a unique 11-digit
|
12
|
+
# number assigned to each Greek citizen or resident who works, pays social
|
13
|
+
# security contributions, or is entitled to healthcare. It follows these rules:
|
14
|
+
#
|
15
|
+
# 1. The first 6 digits represent the date of birth in format DDMMYY
|
16
|
+
# 2. The remaining 5 digits include a check digit based on the Luhn algorithm
|
17
|
+
# 3. The total length is always 11 digits
|
18
|
+
#
|
19
|
+
# @example Validating an AMKA
|
20
|
+
# Amka.valid?('01018012345') #=> true or false
|
21
|
+
#
|
22
|
+
# @example Generating a random AMKA
|
23
|
+
# Amka.generate #=> "21129012345"
|
24
|
+
#
|
25
|
+
# @example Generating an AMKA with specific birth date
|
26
|
+
# Amka.generate('21/12/1990') #=> "21129012345"
|
27
|
+
#
|
28
|
+
# @author Ioannis Angelakopoulos
|
29
|
+
# @since 1.0.0
|
4
30
|
module Amka
|
31
|
+
# Standard error class for the Amka gem
|
32
|
+
class Error < StandardError; end
|
5
33
|
|
34
|
+
# Validates whether a given string is a valid AMKA
|
35
|
+
#
|
36
|
+
# The validation checks three conditions:
|
37
|
+
# 1. The AMKA must be exactly 11 digits long
|
38
|
+
# 2. The first 6 digits must form a valid date (DDMMYY format)
|
39
|
+
# 3. The entire number must satisfy the Luhn algorithm check
|
40
|
+
#
|
41
|
+
# @param amka [String] the AMKA to validate, must be a string containing only digits
|
42
|
+
# @param year [String, nil] optional four-digit year to match against
|
43
|
+
# When provided, improves the validation by ensuring the birth year
|
44
|
+
# matches exactly (resolves century ambiguity in 2-digit years)
|
45
|
+
# @return [Boolean] true if all validation criteria are met, false otherwise
|
46
|
+
# @example Validating with default century assumption
|
47
|
+
# Amka.valid?('17019012345') #=> true
|
48
|
+
# @example Validating with explicit year
|
49
|
+
# Amka.valid?('17019012345', '1990') #=> true
|
6
50
|
def self.valid?(amka, year = nil)
|
7
|
-
Utils.string_with_digits_or_fail
|
51
|
+
Utils.string_with_digits_or_fail(amka)
|
8
52
|
|
9
53
|
return false unless length_is_11?(amka)
|
10
54
|
|
@@ -13,19 +57,40 @@ module Amka
|
|
13
57
|
false
|
14
58
|
end
|
15
59
|
|
60
|
+
# Generates a random valid AMKA
|
61
|
+
#
|
62
|
+
# This method can create an AMKA with either:
|
63
|
+
# - A random valid birth date (when called without parameters)
|
64
|
+
# - A specific birth date (when called with a date parameter)
|
65
|
+
#
|
66
|
+
# The generated AMKA will always satisfy all validation rules:
|
67
|
+
# - 11 digits in length
|
68
|
+
# - First 6 digits form a valid date
|
69
|
+
# - Passes the Luhn algorithm check
|
70
|
+
#
|
71
|
+
# @param date_of_birth [String, nil] optional date in format 'dd/mm/yyyy'
|
72
|
+
# @return [String] a valid AMKA with the first 6 digits representing the
|
73
|
+
# birth date, and the remainder satisfying the Luhn algorithm
|
74
|
+
# @example Generate a random AMKA
|
75
|
+
# Amka.generate #=> "01011912345"
|
76
|
+
# @example Generate an AMKA with specific birth date
|
77
|
+
# Amka.generate('1/1/1990') #=> "01019012345"
|
16
78
|
def self.generate(date_of_birth = nil)
|
17
79
|
return generate_with_date_of_birth(date_of_birth) unless date_of_birth.nil?
|
18
80
|
|
19
|
-
date_6_digits =
|
81
|
+
date_6_digits = String.new
|
20
82
|
loop do
|
21
|
-
day = rand(0..3)
|
83
|
+
day = "#{rand(0..3)}#{rand(0..9)}"
|
22
84
|
next if day == '00' || day.to_i > 31
|
23
|
-
|
85
|
+
|
86
|
+
month = "#{rand(0..1)}#{rand(0..2)}"
|
24
87
|
next if month == '00' || month.to_i > 12
|
25
|
-
|
88
|
+
|
89
|
+
year = "#{rand(19..20)}#{rand(0..9)}#{rand(0..9)}"
|
26
90
|
next if year.to_i > Date.today.year
|
27
91
|
|
28
|
-
|
92
|
+
date = day + month + year[2..3]
|
93
|
+
if Utils.valid_date?(date, year)
|
29
94
|
date_6_digits = date
|
30
95
|
break
|
31
96
|
end
|
@@ -34,23 +99,43 @@ module Amka
|
|
34
99
|
Luhn.generate(11, date_6_digits)
|
35
100
|
end
|
36
101
|
|
102
|
+
# Generates an AMKA with a specific date of birth
|
103
|
+
#
|
104
|
+
# @param date_of_birth [String] date in format 'dd/mm/yyyy'
|
105
|
+
# Day and month can be either 1 or 2 digits
|
106
|
+
# Year must be 4 digits
|
107
|
+
# @return [String] a valid AMKA with the given date of birth
|
108
|
+
# @raise [ArgumentError] if date format is invalid or date is invalid
|
109
|
+
# @example
|
110
|
+
# Amka.generate_with_date_of_birth('1/12/1980') #=> "01128012345"
|
111
|
+
# @example Invalid date raises an error
|
112
|
+
# Amka.generate_with_date_of_birth('31/2/1990')
|
113
|
+
# #=> ArgumentError: The date of birth is invalid!
|
37
114
|
def self.generate_with_date_of_birth(date_of_birth)
|
38
|
-
Utils.string_with_date_or_fail
|
115
|
+
Utils.string_with_date_or_fail(date_of_birth)
|
39
116
|
|
40
|
-
day, month, year = date_of_birth.split('/').map { |i| i.length == 1
|
41
|
-
date_6_digit = day
|
42
|
-
|
117
|
+
day, month, year = date_of_birth.split('/').map { |i| i.length == 1 ? "0#{i}" : i }
|
118
|
+
date_6_digit = day + month + year[2..3]
|
119
|
+
unless Utils.valid_date?(date_6_digit, year)
|
120
|
+
raise ArgumentError, 'The date of birth is invalid!'
|
121
|
+
end
|
43
122
|
|
44
123
|
Luhn.generate(11, date_6_digit)
|
45
124
|
end
|
46
125
|
private_class_method :generate_with_date_of_birth
|
47
126
|
|
127
|
+
# Checks if the ID has exactly 11 digits
|
128
|
+
#
|
129
|
+
# AMKA numbers are required to be exactly 11 digits in length.
|
130
|
+
# This is a validation helper method.
|
131
|
+
#
|
132
|
+
# @param id [String] the ID to check
|
133
|
+
# @return [Boolean] true if length is 11, false otherwise
|
48
134
|
def self.length_is_11?(id)
|
49
135
|
id.length == 11
|
50
136
|
end
|
51
137
|
private_class_method :length_is_11?
|
52
|
-
|
53
138
|
end
|
54
139
|
|
55
|
-
|
56
|
-
|
140
|
+
require_relative 'amka/luhn'
|
141
|
+
require_relative 'amka/utils'
|
metadata
CHANGED
@@ -1,103 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ioannis Angelakopoulos
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: minitest-reporters
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: mocha
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.10'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.10'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '10.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '10.0'
|
83
|
-
description: 'Generates and Validates Greek A.M.K.A (social security number) and Luhn
|
84
|
-
IDs, using the Luhn algorithm. DISCLAIMER: It does not validate the real existence
|
85
|
-
of the A.M.K.A or that it belongs to a given person. The same applies to the generator.'
|
11
|
+
date: 2025-04-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Generates and Validates Greek A.M.K.A and Luhn IDs, using the Luhn algorithm.
|
14
|
+
DISCLAIMER: It does not validate the real existence of the A.M.K.A or that it belongs
|
15
|
+
to a given person. The same applies to the generator.'
|
86
16
|
email:
|
87
17
|
- ioagel@gmail.com
|
88
18
|
executables: []
|
89
19
|
extensions: []
|
90
20
|
extra_rdoc_files: []
|
91
21
|
files:
|
92
|
-
-
|
93
|
-
-
|
94
|
-
- Gemfile
|
22
|
+
- CHANGELOG.md
|
23
|
+
- CONTRIBUTING.md
|
95
24
|
- LICENSE.txt
|
96
25
|
- README.md
|
97
|
-
-
|
98
|
-
- amka.gemspec
|
99
|
-
- bin/console
|
100
|
-
- bin/setup
|
26
|
+
- USAGE.md
|
101
27
|
- lib/amka.rb
|
102
28
|
- lib/amka/luhn.rb
|
103
29
|
- lib/amka/utils.rb
|
@@ -105,8 +31,12 @@ files:
|
|
105
31
|
homepage: https://github.com/ioagel/amka
|
106
32
|
licenses:
|
107
33
|
- MIT
|
108
|
-
metadata:
|
109
|
-
|
34
|
+
metadata:
|
35
|
+
homepage_uri: https://github.com/ioagel/amka
|
36
|
+
source_code_uri: https://github.com/ioagel/amka
|
37
|
+
changelog_uri: https://github.com/ioagel/amka/blob/master/CHANGELOG.md
|
38
|
+
rubygems_mfa_required: 'true'
|
39
|
+
post_install_message:
|
110
40
|
rdoc_options: []
|
111
41
|
require_paths:
|
112
42
|
- lib
|
@@ -114,16 +44,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
44
|
requirements:
|
115
45
|
- - ">="
|
116
46
|
- !ruby/object:Gem::Version
|
117
|
-
version: 2.
|
47
|
+
version: 2.7.0
|
118
48
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
49
|
requirements:
|
120
50
|
- - ">="
|
121
51
|
- !ruby/object:Gem::Version
|
122
52
|
version: '0'
|
123
53
|
requirements: []
|
124
|
-
|
125
|
-
|
126
|
-
signing_key:
|
54
|
+
rubygems_version: 3.4.19
|
55
|
+
signing_key:
|
127
56
|
specification_version: 4
|
128
57
|
summary: AMKA/Luhn IDs Generator and Validator
|
129
58
|
test_files: []
|
data/.gitignore
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.2.3@amka
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/amka.gemspec
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'amka/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "amka"
|
8
|
-
spec.version = Amka::VERSION
|
9
|
-
spec.authors = ["Ioannis Angelakopoulos"]
|
10
|
-
spec.email = ["ioagel@gmail.com"]
|
11
|
-
|
12
|
-
spec.summary = %q{AMKA/Luhn IDs Generator and Validator}
|
13
|
-
spec.description = %q{Generates and Validates Greek A.M.K.A (social security number) and Luhn IDs, using the Luhn algorithm. DISCLAIMER: It does not validate the real existence of the A.M.K.A or that it belongs to a given person. The same applies to the generator.}
|
14
|
-
spec.homepage = "https://github.com/ioagel/amka"
|
15
|
-
spec.license = "MIT"
|
16
|
-
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir = "exe"
|
19
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = ["lib"]
|
21
|
-
spec.required_ruby_version = '>= 2.0.0'
|
22
|
-
|
23
|
-
spec.add_development_dependency "minitest"
|
24
|
-
spec.add_development_dependency "minitest-reporters"
|
25
|
-
spec.add_development_dependency "mocha"
|
26
|
-
spec.add_development_dependency "bundler", "~> 1.10"
|
27
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
-
end
|
data/bin/console
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "amka"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start
|