2015-06-11 3 views
0
t1 = 'This is an example data for testing minhashing' 
t2 = 'This is an example test data for minhashing' 
t3 = 'This is not related at all' 
t4 = t1 
t5 = t3 

# texts = [t1,t2,t3,t4,t5] 

texts = [t1,t2,t3,t4,t5] 

# Define Shingling function 
def shingle(s, l): 
    #Generate k-tuple shingles of a string 
    l = min(len(s), l) 
    return([s[i:i+l] for i in range(len(s) - l + 1)]) 

# Declare punctuation 
exclude = set(string.punctuation) 


# Generate hash functions 
def hash_functions(): 
    def hash_factory(ni): 
     return(lambda x: hash("salt" + str(ni) + str(x) + "salt")) 
    return [hash_factory(i) for i in range(2)] 

# Create list of shingle lists and Normalize text 
shingle_list = [shingle(''.join(ch for ch in d.lower().replace(' ','') if ch not in exclude),4) for d in texts] 

for x in shingle_list: 
    print x 

# Generate LSH matrix 
LIST = [[min(fn(t) for t in tuples) for i, fn in enumerate(hash_functions())] for tuples in shingle_list] 

for x in LIST: 
    print x 

Может кто-нибудь объяснить мне, что хэш-функция упоминается в приведенном выше фрагменте кода, она работает нормально, но я выигрыш понимаю («соль» + ул (п) + ул (х) + «соль).Нужна помощь в понимании питона хэш, реализованный в этой программе

+0

Действительно ли это конкатенация строк (или 'str' вызовов), которые вы не понимаете? Или вы не понимаете _why_ они это делают или как« лямбда »используется для обертывания это как функция или что-то еще, кроме того, что вы задали? – abarnert

+0

Не понимаю, почему автор конкатенирует «соль». – Siddarth

ответ

2

он работает нормально, но я выигрыш понимаю ("соль" + ул (п) + ул (х) + «соль)

Эта часть тривиальна. .

Во-первых, str функции принимает любой объект и преобразует его в строковое представление. Например, ni будет несколько 0 или 1, который str преобразует в строку "0" или "1".

Далее мы просто объединяем четыре строки вместе: "a" + "bc" + "d" + "ef" дает вам "abcdef".


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

Когда вы пишете хеш-функцию для некоторой комбинации значений в терминах более простой хэш-функции, вы должны быть осторожны, чтобы убедиться, что вы включили какое-то «соление», поэтому ваша особая комбинация значений не имеет значения, t случайный хэш в том же виде, что и простая комбинация одних и тех же значений.

Для еще более простого примера рассмотрим этот класс:

class Point(object): 
    def __init__(self, x, y): 
     self.x, self.y = x, y 
    def __hash__(self): 
     return hash((self.x, self.y)) 

Но это означает, что hash((1.0, 2.0)) == hash(Point(1.0, 2.0)). Обычно вы этого не хотите; Точка - это не то же самое, что кортеж, это тип со своей (очень тонкой, но не несуществующей) семантикой. Таким образом, вы вставляете какую-то дополнительную ценность, называемую «солью», в хэш. Например:

class Point(object): 
    def __init__(self, x, y): 
     self.x, self.y = x, y 
    def __hash__(self): 
     return hash((type(self), self.x, self.y)) 

И теперь, hash((1.0, 2.0)) != hash(Point(1.0, 2.0)).

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


Однако стоит упомянуть, что это очень глупа хеш-функция.

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

Во-вторых, единственная причина, по которой вы хотели бы добавить и добавить соль, а не только одну или другую, - это если вы не доверяете функции hash, на которую вы полагаетесь, чтобы обрабатывать части ее равномерно. И действительно, если вы не можете доверять этому, наложение соли на обоих концах не очень помогает - и может нанести боль. (Например, если ваш hash_string недооценивает все после первых нескольких символов, то добавление соли прекрасно предотвращает столкновение с несоленными значениями, а его добавление не будет - но это также означает, что вы нажимаете еще 4 фактических персонажа из избыточного количества символов, что ваши соленые хэши будут еще хуже распределены, чем обычные хэши. Если вы действительно не можете доверять хеш-функции, вы не можете построить более сложную хеш-функцию поверх нее, у вас есть чтобы создать свой собственный.

+0

Спасибо, что нашли время, чтобы подробно объяснить. – Siddarth

1

часть вы выделяете

def hash_functions(): 
    def hash_factory(ni): 
     return(lambda x: hash("salt" + str(ni) + str(x) + "salt")) 
    return [hash_factory(i) for i in range(2)] 

есть функция завода. Вместо hash_factory возвращает значение, она возвращает функцию, эм, функцию зависит от значения, передать его Представьте себе что-то вроде:

def greeting_factory(greeting): 
    return lambda name: greeting + name 

Вы можете использовать это приветствие для создания других функций, например:

say_hola = greeting_factory("Hola, ") 
say_bonjour = greeting_factory("Bonjour, ") 
say_hello = greeting_factory("Hello, ") 
say_howdy = greeting_factory("Howdy, ") 

использовать каждый из тех функций, которые все ожидают один аргумент (имя человека, чтобы сказать привет)

>>> say_hola("Juan") 
Hola, Juan 
>>> say_bonjour("Jacques") 
Bonjour, Jacques 
>>> say_hello("James") 
Hello, James 
>>> say_howdy("pardner") 
Howdy, pardner 

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

def ways_to_say_hello(): 
    def greeting_factory(greeting): 
     return lambda name: greeting + name 
    return [greeting_factory(greet) for greet in ['Hola, ', 'Bonjour, ', 
                'Hello, ', 'Howdy, ']] 

>>> for hello_func in ways_to_say_hello(): 
...  hello_func("Adam Smith") 
Hola, Adam Smith 
Bonjour, Adam Smith 
Hello, Adam Smith 
Howdy, Adam Smith 
+0

Спасибо, что нашли время объяснить. Я не очень хорошо знаком с хэшем, я не понимаю, почему автор конкатенирует «соль». Я понимаю, что str (ni) изменит значение хэша, но зачем нужна «соль»? – Siddarth

+1

@ Сиддарт это не так. Это ужасный пример функции хэширования. Он также делает глупые вещи, такие как 'for i, fn в перечислении (hash_functions())', когда 'i' никогда не используется. По соображениям, почему соление хэша VITALLY важно для более важных функций хеширования (bcrypt, SHA-512 и т. Д.), Вы должны просмотреть http://security.stackexchange.com/questions/51959/why-are-salted-hash-more -ececure, который будет не по теме для обмена стеками. –

+1

@Siddarth Nota Bene: если вы хешируете что-то важное, * НЕ СЛЕДУЕТ СДЕЛАТЬ СОБСТВЕННУЮ ФУНКЦИЮ ХАШ *. Если вы не хешируете ничего важного, используйте встроенную функцию 'хэш' (т.е. хэш (t1)') на основе python. Никогда не существует реальной причины писать собственную функцию хэширования, если вы не удовлетворены отраслевыми стандартами и не имеете опыта, образования и не сделали необходимых исследований, чтобы улучшить его. –

Смежные вопросы