Фиксированная длина числовой хэш-код от строки переменной длины в c#

Кроме того, что упоминали другие, ваш код страдает от проблемы нестабильности типов. Используйте @code_warntype, чтобы проверить это. x имеет элементы типа Float64, а внутри ifelse у вас есть одна ветвь с типом Float64, а другая - с типом Int64. Эту проблему можно решить, используя zero(eltype(x)) вместо 0.

Вместо этого странного условия 2 - 2*x >= 0, используйте это эквивалентное простое x <= 1. Кроме того, вместо вещания я предлагаю использовать map, который работает быстрее и не выделяет. Увидеть ниже.

x = 0:0.1:2
x2 = map(x -> ifelse(x <= 1, 2 - 2x, zero(eltype(x))), x)
14
задан Kishore A 13 February 2009 в 23:57
поделиться

3 ответа

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

Таким образом вот фиксированное и легко повторяемое в другой версии языков.

Я предполагаю, что Вы будете знать во время компиляции количество доступных десятичных цифр. Это основано на Jenkins По одному Хеш (как реализовано и исчерпывающе протестированный Bret Mulvey), как таковой, он имеет превосходное поведение формирования лавины (изменение одного бита во входе распространяет ко всем битам вывода), что означает, что несколько ленивое сокращение по модулю битов в конце не является серьезным дефектом для большей части использования (хотя Вы могли добиться большего успеха с более сложным поведением),

const int MUST_BE_LESS_THAN = 100000000; // 8 decimal digits

public int GetStableHash(string s)
{
    uint hash = 0;
    // if you care this can be done much faster with unsafe 
    // using fixed char* reinterpreted as a byte*
    foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
    {   
        hash += b;
        hash += (hash << 10);
        hash ^= (hash >> 6);    
    }
    // final avalanche
    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    // helpfully we only want positive integer < MUST_BE_LESS_THAN
    // so simple truncate cast is ok if not perfect
    return (int)(hash % MUST_BE_LESS_THAN);
}
23
ответ дан 1 December 2019 в 09:13
поделиться

Использовать System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHash для получения хеша MD5 усеките его к желаемой длине.

0
ответ дан 1 December 2019 в 09:13
поделиться

Простой подход (отмечают, что это зависимо от платформы):

int shorthash = "test".GetHashCode() % 100000000; // 8 zeros
if (shorthash < 0) shorthash *= -1;
6
ответ дан 1 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

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