forked from elixirs/faker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.ex
More file actions
124 lines (103 loc) · 2.95 KB
/
code.ex
File metadata and controls
124 lines (103 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
defmodule Faker.Code do
@moduledoc """
Functions for generate common codes.
"""
alias Faker.Util
@doc """
Returns a random isbn code
## Examples
iex> Faker.Code.isbn
"015426461X"
iex> Faker.Code.isbn
"0832970522"
iex> Faker.Code.isbn
"3570203034"
iex> Faker.Code.isbn
"2097337600"
"""
defdelegate isbn, to: Faker.Code, as: :isbn10
@doc """
Returns a random isbn10 code
## Examples
iex> Faker.Code.isbn10
"015426461X"
iex> Faker.Code.isbn10
"0832970522"
iex> Faker.Code.isbn10
"3570203034"
iex> Faker.Code.isbn10
"2097337600"
"""
def isbn10 do
sequence = Faker.format("#########")
sequence <> check_digit(sequence, &calc_digit_x_index/1, 11)
end
@doc """
Returns a random isbn13 code
## Examples
iex> Faker.Code.isbn13
"9781542646109"
iex> Faker.Code.isbn13
"9783297052358"
iex> Faker.Code.isbn13
"9790203032090"
iex> Faker.Code.isbn13
"9793376033741"
"""
def isbn13 do
sequence = Util.pick(["978", "979"]) <> Faker.format("#########")
sequence <> check_digit(sequence, &calc_isbn13/1, 10)
end
@doc """
Returns a random issn code
## Examples
iex> Faker.Code.issn
"01542648"
iex> Faker.Code.issn
"61083291"
iex> Faker.Code.issn
"70523576"
iex> Faker.Code.issn
"02030322"
"""
def issn do
sequence = Faker.format("#######")
sequence <> check_digit(sequence, &calc_digit_x_index/1, 11)
end
@doc """
Returns a random IBAN starting with the given components. The given components are not validated
but are included in the checksum.
## Examples
iex> Faker.Code.iban("NL", ["ABNA"])
"NL16ABNA0154264610"
iex> Faker.Code.iban("MC", ["FOO", "BAR"])
"MC98FOOBAR83"
iex> Faker.Code.iban("SM", ["A"])
"SM86A2970523570AY38NWIVZ5XT"
iex> Faker.Code.iban("MC", ["FOO", "BAR"])
"MC40FOOBAR60"
"""
defdelegate iban(), to: Faker.Code.Iban
defdelegate iban(country_code_or_codes), to: Faker.Code.Iban
defdelegate iban(country_code, prefix_components), to: Faker.Code.Iban
defp check_digit(sequence, calc_function, size) do
(sequence <> "0")
|> String.reverse()
|> String.graphemes()
|> Stream.with_index()
|> Stream.map(calc_function)
|> Enum.sum()
|> grapheme_for_last(size)
end
defp grapheme_for_last(checksum, size) do
digit_to_grapheme(size - rem(checksum, size), size)
end
defp calc_digit_x_index({e, i}), do: grapheme_to_digit(e) * (i + 1)
defp calc_isbn13({e, i}) when rem(i, 2) == 1, do: grapheme_to_digit(e) * 3
defp calc_isbn13({e, _}), do: grapheme_to_digit(e)
defp digit_to_grapheme(10, 11), do: "X"
defp digit_to_grapheme(digit, size) when digit == size, do: "0"
defp digit_to_grapheme(digit, _), do: Integer.to_string(digit)
defp grapheme_to_digit("X"), do: 10
defp grapheme_to_digit(str), do: String.to_integer(str)
end