add passcode generator
This commit is contained in:
parent
94ef1e22b8
commit
b6260a950f
1 changed files with 15 additions and 15 deletions
|
|
@ -15,7 +15,7 @@ defmodule Aprs.Passcode do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
iex> Aprs.Passcode.generate("W5ISP")
|
iex> Aprs.Passcode.generate("W5ISP")
|
||||||
12345
|
15748
|
||||||
"""
|
"""
|
||||||
def generate(callsign) when is_binary(callsign) do
|
def generate(callsign) when is_binary(callsign) do
|
||||||
# Split on '-' and take first part, uppercase, and limit to 10 chars
|
# Split on '-' and take first part, uppercase, and limit to 10 chars
|
||||||
|
|
@ -32,22 +32,22 @@ defmodule Aprs.Passcode do
|
||||||
# Initial hash value
|
# Initial hash value
|
||||||
hash = 0x73E2
|
hash = 0x73E2
|
||||||
|
|
||||||
# Process characters in pairs
|
# Process characters in pairs, incrementing by 2 each time
|
||||||
hash =
|
hash =
|
||||||
Enum.reduce_every(chars, 2, hash, fn [char1, char2], acc ->
|
Enum.reduce(0..div(length(chars) - 1, 2), hash, fn i, acc ->
|
||||||
acc
|
current_char = Enum.at(chars, i * 2)
|
||||||
|> Bitwise.bxor(Bitwise.bsl(char1, 8))
|
next_char = if i * 2 + 1 < length(chars), do: Enum.at(chars, i * 2 + 1), else: nil
|
||||||
|> Bitwise.bxor(char2)
|
step1 = Bitwise.bxor(acc, Bitwise.bsl(current_char, 8))
|
||||||
end)
|
|
||||||
|
|
||||||
# Handle odd length callsigns
|
step2 =
|
||||||
hash =
|
if next_char do
|
||||||
if rem(length(chars), 2) == 1 do
|
Bitwise.bxor(step1, next_char)
|
||||||
last_char = List.last(chars)
|
else
|
||||||
Bitwise.bxor(hash, Bitwise.bsl(last_char, 8))
|
step1
|
||||||
else
|
end
|
||||||
hash
|
|
||||||
end
|
step2
|
||||||
|
end)
|
||||||
|
|
||||||
# Return final hash masked to 15 bits
|
# Return final hash masked to 15 bits
|
||||||
Bitwise.band(hash, 0x7FFF)
|
Bitwise.band(hash, 0x7FFF)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue