Skip to content

Commit 21bc107

Browse files
Fix decoding when alphabet contains regex-like special chars (#10)
Fix decoding when the alphabet contains regex-like special chars.
1 parent 4893e1b commit 21bc107

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

src/main/java/org/sqids/Sqids.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,23 @@ public List<Long> decode(final String id) {
137137
.append(this.alphabet, 0, offset)
138138
.reverse()
139139
.toString();
140-
String slicedId = id.substring(1);
141140

142-
while (!slicedId.isEmpty()) {
141+
int index = 1;
142+
while (true) {
143143
final char separator = alphabet.charAt(0);
144-
final String[] chunks = slicedId.split(String.valueOf(separator), 2);
145-
final int chunksLength = chunks.length;
146-
if (chunksLength > 0) {
147-
if (chunks[0].isEmpty()) {
148-
return ret;
149-
}
150-
ret.add(toNumber(chunks[0], alphabet.substring(1)));
151-
if (chunksLength > 1) {
152-
alphabet = shuffle(alphabet);
153-
}
144+
int separatorIndex = id.indexOf(separator, index);
145+
if (separatorIndex == -1) {
146+
separatorIndex = id.length();
147+
} else if (index == separatorIndex) {
148+
break;
149+
}
150+
ret.add(toNumber(id, index, separatorIndex, alphabet.substring(1)));
151+
index = separatorIndex + 1;
152+
if (index < id.length()) {
153+
alphabet = shuffle(alphabet);
154+
} else {
155+
break;
154156
}
155-
slicedId = chunksLength > 1 ? chunks[1] : "";
156157
}
157158
return ret;
158159
}
@@ -230,15 +231,13 @@ private StringBuilder toId(long num, final String alphabet) {
230231
return id.reverse();
231232
}
232233

233-
private long toNumber(final String id, final String alphabet) {
234-
char[] chars = alphabet.toCharArray();
235-
int charLength = chars.length;
234+
private long toNumber(final String id, final int fromInclusive, final int toExclusive, final String alphabet) {
235+
int alphabetLength = alphabet.length();
236236
long number = 0;
237-
238-
for (char c : id.toCharArray()) {
239-
number = number * charLength + alphabet.indexOf(c);
237+
for (int i = fromInclusive; i < toExclusive; i++) {
238+
char c = id.charAt(i);
239+
number = number * alphabetLength + alphabet.indexOf(c);
240240
}
241-
242241
return number;
243242
}
244243

src/test/java/org/sqids/AlphabetTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ public void shortAlphabet() {
2727
Assertions.assertEquals(sqids.decode(sqids.encode(numbers)), numbers);
2828
}
2929

30+
@Test
31+
public void specialCharsAlphabet() {
32+
Sqids sqids = Sqids.builder()
33+
.alphabet(".\\?")
34+
.build();
35+
List<Long> numbers = Arrays.asList(1L, 2L, 3L);
36+
Assertions.assertEquals(sqids.decode(sqids.encode(numbers)), numbers);
37+
}
38+
3039
@Test
3140
public void multibyteCharacters() {
3241
Assertions.assertThrows(IllegalArgumentException.class, () -> Sqids.builder()

0 commit comments

Comments
 (0)