Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Хэш-функции на основе деления

Читайте также:
  1. IV Соотнесите слова с их определениями.
  2. S4.6 Определения
  3. А. Однофазное прикосновение в сетях с заземленной нейтралью
  4. А. Статистические оценки и законы распределения.
  5. АЛГОРИТМ ДЕЛЕНИЯ В СИСТЕМЕ С ОТРИЦАТЕЛЬНЫМ ОСНОВАНИЕМ.
  6. Алгоритм определения средней величины, среднеквадратического отклонения и ошибки средней величины
  7. Алгоритм поиска подстроки Кнута-Морриса-Пратта (на основе префикс-функции)

Пусть требуется для числа A получить значение хэш-функции. Предлагается в качестве хэш-функции использовать остаток от деления A на некоторое K

h(A)=A (mod K)

Если A имеет довольно большую длину (например, A – строка текста), то данный алгоритм применим и в этом случае. Будем далее остаток от деления обозначать через оператор %. Представим A как число в позиционной системе счисления

A=Sk=0k<N r kck

где r=256 (в общем случае r – основание системы счисления, в которой представляется число A), ck –значение k -ой цифры в представлении A (в нашем случае = код k -ого символа строки), N – количество знаков (цифр) в представлении A. Будем предполагать, что

K<r.

Легко увидеть, что

(r N-1 cN-1 + r N-2 cN-2)%K= (r N-2 ((r cN-1 + cN-2)%K))%K

Из чего сразу получаем, что

h(A)=(Sk=0k<N r kck)%K = (Sk=0k<N-1 r kdk)%K,

где dN-2=(r cN-1 + cN-2)%K, di = ci (i<N-2).

Т.о. следующая подпрограмма вычисляет хэш-функцию на основе деления от строки текста

int hash(unsigned char *str, int K)

{unsigned short int p=0;

if(str[0]=='\0')return 0;

if(str[1]=='\0')return str[0]%K;

p=str[0];

while(str[1]!='\0')

{

p=(p<<8)|str[1];

p=p%K;

str++;

}

Return p;

}

Хэш-функции на основе умножения

Алгоритм вычисления хэш-функции, основывающийся на умножении, задается следующей формулой

h(A) = [M({AK/ R})]

здесь фигурные скобки являются оператором взятия дробной части, квадратные скобки являются оператором взятия целой части, R – размер машинного слова, в котором размещается A (например, если A размещается в целой 32-битной переменной, то R=232), K – некоторое число, взаимно простое с R. В качестве M часто выгодно брать M=2m.

Алгоритм является обобщением алгоритма, основанного на делении. Действительно, пусть K есть некоторое приближение к R/S, M=S, то

h(A) = [M({AK/ R})] = [S({A / S})]» A%S

Практически, алгоритм сводится к следующему: ставится десятичная точка перед числом A, полученное число умножается на K, из результата берутся первые m бит, расположенных после десятичной точки (здесь под десятичной точкой имеется в виду разделитель целой и дробной части в позиционной системе отсчета).

В случае, когда A представляет собой строку текста, состоящую из n байт, то, опять же, A рассматривается как число в позиционной системе исчисления. В этом случае R=256 n.

Умножение можно производить `столбиком’, тогда для m£16 подпрограмма вычисления хэш-функции имеет следующий вид

int hashm(unsigned char *str, int K, int m)

{union ICHAR {unsigned int i; unsigned char c[4];}s,srez,sm;

int rez,l,i; l=strlen((char*)str); srez.i=s.i=sm.i=0;

for(i=l-1;i>=0;i--)

{

srez.c[0]=s.c[0]; //кладем младший байт из пред.знач.

s.i=0; s.c[0]=str[i];

s.i*=K; //умножаем K на очередную цифру

s.i+=sm.i; //добавляем запомненное

sm.c[0]=s.c[1];sm.c[1]=s.c[2];sm.c[2]=s.c[3];sm.c[3]=0;

srez.c[1]=s.c[0];

}

rez=srez.i>>(16-m); //извлекаем m бит после точки

Return rez;

}

 

Здесь мы ввели union ICHAR для того, чтобы иметь возможность обращаться к отдельным байтам целой переменной.В цикле мы умножаем K на каждый байт строки и добавляем к результату то, что осталось от переполнения в предыдущем умножении. При этом под переполнение отводится 3 старших байта переменной s, а под основную цифру – один младший байт. Результат переполнения хранится в переменной sm. Т.к. конечный результат может занимать до двух байт, приходится вводить дополнительную переменную srez, для хранения последних байт произведения str*K.


Дата добавления: 2015-10-30; просмотров: 126 | Нарушение авторских прав


Читайте в этой же книге: Сбалансированные и идеально сбалансированные бинарные деревья поиска | Добавление элемента в дерево | Разбиение дерева по разбивающему элементу | Добавление элемента в красно-черное дерево | Однопроходное добавление элемента в красно-черное дерево | Удаление элемента из красно-черного дерева | Отступление на тему языка С. Быстрый поиск и сортировка в языке С | Удаление вершины из B-дерева | Метод линейных проб | Доказательство. |
<== предыдущая страница | следующая страница ==>
Метод цепочек| CRC-алгоритмы обнаружения ошибок

mybiblioteka.su - 2015-2024 год. (0.008 сек.)