Краткий ответ на ваш вопрос о хешировании: «используйте SHA-256». Это ответ практически для любой проблемы с безопасным хешированием, если только ответ не «используйте SHA-512». Если вам нужен 128-битный хэш, вы можете обрезать SHA-256 (взять первые или последние 128 битов). Все биты в SHA-256 независимы, поэтому вы можете извлечь любые 128 из них как хэш.
Тем не менее, ИМО, вы неправильно думаете об этой проблеме. Дело не в защите SessionId конкретно.Проблема в том, что URL-адреса могут содержать конфиденциальную информацию, одним из примеров которой является SessionId (если он хранится в URL-адресе). Если кто-то уже знает сокращенный URL-адрес, он может просто запросить у вашей системы полный URL-адрес, так что это все для того, чтобы злоумышленники не могли найти ключи путем угадывания. Вам нужно сделать ваше пространство ключей разреженным, то есть сказать «намного, намного больше, чем количество фактически сохраненных ключей».
Вы поддерживаете базу данных ключей/значений, поэтому вообще нет необходимости использовать хэш. Вы можете просто сгенерировать случайный ключ для каждого URL. Это лучше, чем хеш, потому что между ключом и значением нет абсолютно никакой связи.
Учитывая ваш дизайн, злоумышленники не могут осуществлять поиск в автономном режиме. Они должны связаться с вашим сервером. Скажем, вы можете обслуживать 1000 запросов в секунду и масштабируете общее пространство ключей так, чтобы оно в триллион раз превышало запланированное количество URL-адресов. Злоумышленнику потребовалось бы примерно 15 000 лет (~ 1/2 поискового пространства), чтобы найти один URL-адрес, если бы они могли использовать всю доступную пропускную способность (что, я ожидаю, вы могли бы заметить....). С небольшим ограничением скорости для каждого IP-адреса вы можете значительно усложнить эту атаку.
Учитывая вышеизложенное, если вы хотите хранить миллиард URL-адресов в своей системе, вам понадобится пространство ключей:
log2 (1 миллиард URL * 1 триллион множителя) = 80 бит
В Base58 (который мне нравится для такого рода задач, потому что он удобен для человека) это заняло бы около 14 символов. Изменяя приведенные выше значения для ограничения скорости, периода атаки, от которой вы хотите защитить, и количества сохраненных URL-адресов, вы можете выбрать длину ваших ключей.
Как правило, вы можете вычислять случайные значения в этом масштабе, не беспокоясь о коллизиях (что хорошо для производительности). По той же причине, по которой злоумышленнику крайне сложно найти столкновение, крайне маловероятно, что оно возникнет случайно. Но если вы хотите перепроверить просто как маловероятно, посмотри Атака на день рождения. Вычисления «какова вероятность того, что любые значения сталкиваются» отличаются от «сколько времени потребуется злоумышленнику, чтобы найти коллизию», и в некоторых случаях заставят вас использовать более длинные ключи.
ИМО нет необходимости в хэшах. Но если он вам нужен, используйте SHA-256, усеченный до любого количества битов, которое вы хотите.