Самый короткий хеш в Python для именования файлов кэша

Я всегда рекомендую использовать свободное городское население Apache, так как это, скорее всего, будет лучше, чем одно, можно записать самостоятельно. Плюс Вы может затем сделать 'реальную' работу скорее затем переосмысление.

класс, которым Вы интересуетесь, Пустой Компаратор . Это позволяет, Вы для создания аннулируете высоко или низко. Вы также даете ему свой собственный компаратор для использования, когда два значения не являются нулевыми.

В Вашем случае у Вас может быть статическая членская переменная, которая делает сравнение и затем Ваш compareTo метод просто ссылки это.

Somthing как

class Metadata implements Comparable {
private String name;
private String value;

static NullComparator nullAndCaseInsensitveComparator = new NullComparator(
        new Comparator() {

            @Override
            public int compare(String o1, String o2) {
                // inputs can't be null
                return o1.compareToIgnoreCase(o2);
            }

        });

@Override
public int compareTo(Metadata other) {
    if (other == null) {
        return 1;
    }
    int res = nullAndCaseInsensitveComparator.compare(name, other.name);
    if (res != 0)
        return res;

    return nullAndCaseInsensitveComparator.compare(value, other.value);
}

}

, Даже если Вы решаете к самокрутке, помните об этом классе, так как это очень полезно при упорядочивании списков thatcontain пустые элементы.

18
задан u0b34a0f6ae 20 August 2009 в 11:16
поделиться

8 ответов

Применяется парадокс дня рождения : с учетом хорошей хеш-функции ожидаемое количество хешей до возникновения коллизии составляет примерно sqrt (N ), где N - количество различных значений, которые может принимать хеш-функция. (В статье в Википедии, на которую я указал, дана точная формула). Так, например, если вы хотите использовать не более 32 битов, ваши опасения по поводу коллизии серьезны для примерно 64K объектов (то есть 2 ** 16 объектов - квадратный корень из 2 ** 32 разных значения, которые может принимать ваша хеш-функция). Сколько объектов вы ожидаете иметь в порядке величины?

Поскольку вы упомянули, что столкновение - незначительное раздражение, я рекомендую вам стремиться к длине хэша, равной ' s примерно квадрат количества объектов, которые у вас будут, или немного меньше, но не НАМНОГО меньше этого.

Вы хотите создать имя файла - это то, что в файловой системе с учетом регистра, как обычно в Unix, или вам тоже нужно обслуживать системы без учета регистра? Это важно, потому что вы стремитесь к коротким именам файлов, но количество битов на символ, которое вы можете использовать для представления вашего хэша, поскольку имя файла резко меняется в системах с учетом регистра и без учета регистра.

В системе с учетом регистра вы можете использовать модуль стандартной библиотеки base64 (я рекомендую "urlsafe" версию кодировки, то есть эту функцию, поскольку в именах файлов Unix важно избегать символов '/', которые могут присутствовать в простом base64 ). Это дает вам 6 используемых битов на символ, что намного лучше, чем 4 бита на символ в шестнадцатеричном формате.

Даже в системе, нечувствительной к регистру, вы все равно можете работать лучше, чем шестнадцатеричный - используйте base64.b32encode и получите 5 бит на символ.

Эти функции принимают и возвращают строки; используйте модуль struct для преобразования чисел в строки, если выбранная вами хеш-функция генерирует числа.

Если у вас есть несколько десятков тысяч объектов, я думаю, вы будете в порядке со встроенным хешем (32 бита , поэтому 6-7 символов в зависимости от выбранной кодировки). Для миллиона объектов вам понадобится 40 бит или около того (7 или 8 символов) - вы можете свернуть (xor, не обрезать ;-) sha256 до длинного с разумным количеством бит, скажем, 128 или около того , и используйте оператор % , чтобы сократить его до желаемой длины перед кодированием.

b32 кодирует и получает 5 бит на символ.

Эти функции принимают и возвращают строки; используйте модуль struct для преобразования чисел в строки, если выбранная вами хеш-функция генерирует числа.

Если у вас есть несколько десятков тысяч объектов, я думаю, вы будете в порядке со встроенным хешем (32 бита , поэтому 6-7 символов в зависимости от выбранной кодировки). Для миллиона объектов вам понадобится 40 бит или около того (7 или 8 символов) - вы можете свернуть (xor, не обрезать ;-) sha256 до длинного с разумным количеством бит, скажем, 128 или около того , и используйте оператор % , чтобы сократить его до желаемой длины перед кодированием.

b32 кодирует и получает 5 бит на символ.

Эти функции принимают и возвращают строки; используйте модуль struct для преобразования чисел в строки, если выбранная вами хеш-функция генерирует числа.

Если у вас есть несколько десятков тысяч объектов, я думаю, вы будете в порядке со встроенным хешем (32 бита , поэтому 6-7 символов в зависимости от выбранной кодировки). Для миллиона объектов вам понадобится 40 бит или около того (7 или 8 символов) - вы можете свернуть (xor, не обрезать ;-) sha256 до длинного с разумным количеством бит, скажем, 128 или около того , и используйте оператор % , чтобы сократить его до желаемой длины перед кодированием.

Если у вас есть несколько десятков тысяч объектов, я думаю, вам подойдет встроенный хеш (32 бита, то есть 6-7 символов в зависимости от выбранной вами кодировки). Для миллиона объектов вам понадобится 40 бит или около того (7 или 8 символов) - вы можете свернуть (xor, не обрезать ;-) sha256 до длинного с разумным количеством бит, скажем, 128 или около того , и используйте оператор % , чтобы сократить его до желаемой длины перед кодированием.

Если у вас есть несколько десятков тысяч объектов, я думаю, вам подойдет встроенный хэш (32 бита, то есть 6-7 символов в зависимости от выбранной кодировки). Для миллиона объектов вам понадобится 40 бит или около того (7 или 8 символов) - вы можете свернуть (xor, не обрезать ;-) sha256 до длинного с разумным количеством бит, скажем, 128 или около того , и используйте оператор % , чтобы сократить его до желаемой длины перед кодированием.

37
ответ дан 30 November 2019 в 05:45
поделиться

Встроенная хеш-функция строк довольно свободна от конфликтов и довольно коротка. Он имеет 2 ** 32 значений, поэтому вероятность столкновения маловероятна (если вы используете его значение abs, оно будет иметь только 2 ** 31 значений).

Вы просили самую короткую хеш-функцию. Это определенно будет

def hash(s):
  return 0

, но я полагаю, вы на самом деле не это имели в виду ...

26
ответ дан 30 November 2019 в 05:45
поделиться

Любой хеш-код можно сделать короче, просто усек его. md5 всегда состоит из 32 шестнадцатеричных цифр, но его произвольная подстрока (или любой другой хэш) обладает надлежащими качествами хэша: равные значения производят равные хэши, а значения распределяются по группе.

7
ответ дан 30 November 2019 в 05:45
поделиться

Я уверен, что в Python есть реализация CRC32, но она может быть слишком короткой (8 шестнадцатеричных цифр). С другой стороны, это очень быстро.

Нашел, binascii.crc32

3
ответ дан 30 November 2019 в 05:45
поделиться

Если у вас действительно есть столкновение, как вы собираетесь узнать, что оно произошло на самом деле?

На вашем месте я бы использовал hashlib для sha1 () repr () , а затем просто получите его ограниченную подстроку (например, первые 16 символов).

Если вы не говорите об огромном количестве этих объектов, я бы посоветовал вам просто использовать полный хеш. Тогда возможность столкновения настолько, так, так мала, что вы никогда не доживете, чтобы увидеть, как это произойдет (вероятно).

Кроме того, если вы имеете дело с , что много файлов, я ' я предполагаю, что ваш метод кэширования должен быть адаптирован к нему.

1
ответ дан 30 November 2019 в 05:45
поделиться

Мы используем hashlib.sha1.hexdigest (), который производит еще более длинные строки для объектов кеширования с хорошим успехом. В любом случае, никто не просматривает файлы кеша.

1
ответ дан 30 November 2019 в 05:45
поделиться

Рассматривая ваш вариант использования, если вы не настроены на использование отдельных файлов кэша и не слишком далеко продвинулись по этому пути разработки, вы можете рассмотреть возможность использования полки .

Это даст вам постоянный словарь (хранящийся в одном файле dbm), в котором вы храните свои объекты. Сбор / распаковка выполняется прозрачно, и вам не нужно беспокоиться о хешировании, коллизиях, вводе-выводе файлов и т. Д.

Для ключей словаря полки вы должны просто использовать repr (obj) и позволить shelve занимается хранением ваших предметов за вас. Простой пример:

import shelve
cache = shelve.open('cache')
t = (1,2,3)
i = 10
cache[repr(t)] = t
cache[repr(i)] = i
print cache
# {'(1, 2, 3)': (1, 2, 3), '10': 10}
cache.close()

cache = shelve.open('cache')
print cache
#>>> {'(1, 2, 3)': (1, 2, 3), '10': 10}
print cache[repr(10)]
#>>> 10
1
ответ дан 30 November 2019 в 05:45
поделиться

Короткие хэши означают, что у вас может быть один и тот же хеш для двух разных файлов. То же самое может случиться и с большими хешами, но это реже. Возможно, эти имена файлов должны отличаться в зависимости от других ссылок, например microtime (если только эти файлы не создаются слишком быстро).

0
ответ дан 30 November 2019 в 05:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: