yomorun / hashids-java

Hashids algorithm v1.0.0 implementation in Java
http://hashids.org
MIT License
1.02k stars 156 forks source link

ArrayIndexOutOfBoundsException from encode(long... numbers) #30

Closed philbayer closed 7 years ago

philbayer commented 7 years ago

Problem: If the list of longs passed to the method public String encode(long... numbers) contains a negative value, it may result in a java.lang.ArrayIndexOutOfBoundsException being thrown. Here is the offending code snippet (see added inline comments.

  private String _encode(long... numbers){
    int numberHashInt = 0;
    for(int i = 0; i < numbers.length; i++){
      numberHashInt += (numbers[i] % (i+100));  // If numbers contains a negative long value then numberHashInt could be negative
    }
    String alphabet = this.alphabet;
    char ret = alphabet.toCharArray()[numberHashInt % alphabet.length()]; // if numberHashInt is negative, an ArrayIndexOutOfBoundsException will be thrown

Possible Solutions: 1) In the method public String encode(long... numbers) replace the following line

if (number > 9007199254740992L) {

with

if (number > 9007199254740992L || number < 0) {

2) In the method private String _encode(long... numbers) use the absolute value of the long values in numbers when computing the hash:

int numberHashInt = 0;
for(int i = 0; i < numbers.length; i++){
  numberHashInt += (Math.abs(numbers[i]) % (i+100));
}
0x3333 commented 7 years ago

Fixed.

When encoding negative numbers, the result should be ""(empty string), same behaviour as the javascript implementation.

https://github.com/ivanakimov/hashids.js/blob/master/lib/hashids.js#L111-L115

0x3333 commented 7 years ago

Just to make it clear, the fix has not been released. It has been fixed in HEAD.