Skip to content

Commit 2db5a1a

Browse files
committed
PR2 Move _encode method to free function encode in impl package.
1 parent 49c6ab1 commit 2db5a1a

File tree

2 files changed

+73
-67
lines changed

2 files changed

+73
-67
lines changed

hashids-scala/src/main/scala/org/hashids/Hashids.scala

Lines changed: 9 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ class Hashids(
5151
}
5252
}
5353

54-
def encode(numbers: Long*): String = if (numbers.isEmpty) "" else _encode(numbers:_*)
54+
def encode(numbers: Long*): String = {
55+
if (numbers.isEmpty) {
56+
""
57+
} else {
58+
org.hashids.impl.encode(numbers:_*)(effectiveAlphabet, minHashLength, salt, seps, guards)
59+
}
60+
}
5561

5662
def encodeHex(in: String): String = {
5763
require(in.matches("^[0-9a-fA-F]+$"), "Not a HEX string")
@@ -66,76 +72,13 @@ class Hashids(
6672
result
6773
}
6874

69-
_encode(doSplit(Nil):_*)
70-
}
71-
72-
private def _encode(numbers: Long*): String = {
73-
val indexedNumbers = numbers.zipWithIndex
74-
val numberHash = indexedNumbers
75-
.foldLeft[Int](0){ case (acc, (x, i)) =>
76-
acc + (x % (i+100)).toInt
77-
}
78-
val lottery = effectiveAlphabet.charAt(numberHash % effectiveAlphabet.length).toString
79-
80-
val (tmpResult, tmpAlpha) =
81-
indexedNumbers.foldLeft[(String, String)]((lottery, effectiveAlphabet)) {
82-
case ((result, alpha), (x, i)) =>
83-
val buffer = lottery + salt + alpha
84-
val newAlpha = consistentShuffle(alpha, buffer.substring(0, alpha.length))
85-
val last = hash(x, newAlpha)
86-
val newResult = result + last
87-
88-
if (i + 1 < numbers.size) {
89-
val num = x % (last.codePointAt(0) + i)
90-
val sepsIndex = (num % seps.length).toInt
91-
(newResult + seps.charAt((num % seps.length).toInt), newAlpha)
92-
} else {
93-
(newResult, newAlpha)
94-
}
95-
}
96-
97-
val provisionalResult = {
98-
if (tmpResult.length < minHashLength) {
99-
val guardIndex = (numberHash + tmpResult.codePointAt(0)) % guards.length
100-
val guard = guards.charAt(guardIndex)
101-
102-
val provResult = guard + tmpResult
103-
104-
if (provResult.length < minHashLength) {
105-
val guardIndex = (numberHash + provResult.codePointAt(2)) % guards.length
106-
val guard = guards.charAt(guardIndex)
107-
provResult + guard
108-
} else {
109-
provResult
110-
}
111-
} else tmpResult
112-
}
113-
114-
val halfLen = tmpAlpha.length / 2
115-
116-
@tailrec
117-
def respectMinHashLength(alpha: String, res: String): String = {
118-
if (res.length >= minHashLength) {
119-
res
120-
} else {
121-
val newAlpha = consistentShuffle(alpha, alpha);
122-
val tmpRes = newAlpha.substring(halfLen) + res + newAlpha.substring(0, halfLen);
123-
val excess = tmpRes.length - minHashLength
124-
val newRes = if(excess > 0) {
125-
val startPos = excess / 2
126-
tmpRes.substring(startPos, startPos + minHashLength)
127-
} else tmpRes
128-
respectMinHashLength(newAlpha, newRes)
129-
}
130-
}
131-
132-
respectMinHashLength(tmpAlpha, provisionalResult)
75+
org.hashids.impl.encode(doSplit(Nil):_*)(effectiveAlphabet, minHashLength, salt, seps, guards)
13376
}
13477

13578
def decode(hash: String): List[Long] = hash match {
13679
case "" => Nil
13780
case x =>
138-
val res = org.hashids.impl.decode(x, effectiveAlphabet, salt, seps, guards)
81+
val res = org.hashids.impl.decode(x)(effectiveAlphabet, salt, seps, guards)
13982
if (encode(res:_*) == hash) res else Nil
14083
}
14184

hashids-scala/src/main/scala/org/hashids/impl/package.scala

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,70 @@ package object impl {
4848
}
4949
}
5050

51-
def decode(hash: String, effectiveAlphabet: String, salt: String, seps: String, guards: String): List[Long] = {
51+
def encode(numbers: Long*)(effectiveAlphabet: String, minHashLength: Int, salt: String, seps: String, guards: String): String = {
52+
val indexedNumbers = numbers.zipWithIndex
53+
val numberHash = indexedNumbers
54+
.foldLeft[Int](0){ case (acc, (x, i)) =>
55+
acc + (x % (i+100)).toInt
56+
}
57+
val lottery = effectiveAlphabet.charAt(numberHash % effectiveAlphabet.length).toString
58+
59+
val (tmpResult, tmpAlpha) =
60+
indexedNumbers.foldLeft[(String, String)]((lottery, effectiveAlphabet)) {
61+
case ((result, alpha), (x, i)) =>
62+
val buffer = lottery + salt + alpha
63+
val newAlpha = consistentShuffle(alpha, buffer.substring(0, alpha.length))
64+
val last = hash(x, newAlpha)
65+
val newResult = result + last
66+
67+
if (i + 1 < numbers.size) {
68+
val num = x % (last.codePointAt(0) + i)
69+
val sepsIndex = (num % seps.length).toInt
70+
(newResult + seps.charAt((num % seps.length).toInt), newAlpha)
71+
} else {
72+
(newResult, newAlpha)
73+
}
74+
}
75+
76+
val provisionalResult = {
77+
if (tmpResult.length < minHashLength) {
78+
val guardIndex = (numberHash + tmpResult.codePointAt(0)) % guards.length
79+
val guard = guards.charAt(guardIndex)
80+
81+
val provResult = guard + tmpResult
82+
83+
if (provResult.length < minHashLength) {
84+
val guardIndex = (numberHash + provResult.codePointAt(2)) % guards.length
85+
val guard = guards.charAt(guardIndex)
86+
provResult + guard
87+
} else {
88+
provResult
89+
}
90+
} else tmpResult
91+
}
92+
93+
val halfLen = tmpAlpha.length / 2
94+
95+
@tailrec
96+
def respectMinHashLength(alpha: String, res: String): String = {
97+
if (res.length >= minHashLength) {
98+
res
99+
} else {
100+
val newAlpha = consistentShuffle(alpha, alpha);
101+
val tmpRes = newAlpha.substring(halfLen) + res + newAlpha.substring(0, halfLen);
102+
val excess = tmpRes.length - minHashLength
103+
val newRes = if(excess > 0) {
104+
val startPos = excess / 2
105+
tmpRes.substring(startPos, startPos + minHashLength)
106+
} else tmpRes
107+
respectMinHashLength(newAlpha, newRes)
108+
}
109+
}
110+
111+
respectMinHashLength(tmpAlpha, provisionalResult)
112+
}
113+
114+
def decode(hash: String)(effectiveAlphabet: String, salt: String, seps: String, guards: String): List[Long] = {
52115
val hashArray = hash.split(s"[$guards]")
53116
val i = if (hashArray.length == 3 || hashArray.length == 2) 1 else 0
54117
val lottery = hashArray(i).charAt(0)

0 commit comments

Comments
 (0)