Процедура быстрого удаления дубликатов:
/* create temp table with one primary column id */
INSERT INTO temp(id) SELECT MIN(id) FROM list GROUP BY (isbn) HAVING COUNT(*)>1;
DELETE FROM list WHERE id IN (SELECT id FROM temp);
DELETE FROM temp;
Почему бы вам просто не усечь SHA1 или MD5? У вас будет больше коллизий, если бы вы не усекали, но это все равно лучше, чем создавать свои собственные. Обратите внимание, что вы можете кодировать усеченный хэш с помощью base64, а не использовать шестнадцатеричный. Например.
import base64
import hashlib
hasher = hashlib.sha1("The quick brown fox")
base64.urlsafe_b64encode(hasher.digest()[:10])
Вы можете обрезать настолько мало (в том числе совсем не) или столько, сколько хотите, если вы понимаете компромиссы.
РЕДАКТИРОВАТЬ: поскольку вы упомянули безопасный URL-адрес, вы можете использовать urlsafe_b64encode и urlsafe_b64decode , который использует -
и _
, а не +
и /
.
Самый маленький встроенный хэш, о котором я знаю, это md5
>>> import hashlib, base64
>>> d=hashlib.md5(b"hello worlds").digest(); d=base64.b64encode(d);
>>> print(d)
b'S27ylES0wiLdFAGdUpFgCQ=='
Низкая коллизия и короткость в некоторой степени взаимоисключающие понятия из-за парадокса дня рождения
Чтобы сделать его urlsafe, нужно использовать функцию из модуля base64
>>> import base64
>>> base64.urlsafe_b64encode(hashlib.md5("hello world").digest())
'XrY7u-Ae7tCTyyK7j1rNww=='
Однако не должно быть проблем с хранением 16-байтового дайджеста md5 в базе данных в двоичной форме.
>>> md5bytes=hashlib.md5("hello world").digest()
>>> len(md5bytes)
16
>>> urllib.quote_plus(md5bytes)
'%5E%B6%3B%BB%E0%1E%EE%D0%93%CB%22%BB%8FZ%CD%C3'
Python 2
>>> base64.urlsafe_b64encode(md5bytes)
'XrY7u-Ae7tCTyyK7j1rNww=='
Python 3
>>> base64.urlsafe_b64encode(md5bytes).decode('ascii')
'XrY7u-Ae7tCTyyK7j1rNww=='
Вы можете выбрать quote_plus
или urlsafe_b64encode
для вашего url, а затем декодировать соответствующей функцией unquote_plus
или urlsafe_b64decode
, прежде чем искать их в базе данных.
Ниже представлено решение, в котором используются буквенно-цифровые символы плюс несколько знаков пунктуации. Он возвращает очень короткие строки (около 8 символов).
import binascii, struct
def myhash(s):
return binascii.b2a_base64(struct.pack('i', hash(s)))