Wybór właściwego algorytmu w funkcji HashBytes

20

Musimy utworzyć wartość skrótu danych nvarchar do celów porównawczych. W T-SQL dostępnych jest wiele algorytmów mieszania, ale który z nich najlepiej wybrać w tym scenariuszu?

Chcemy zapewnić, aby ryzyko posiadania podwójnej wartości skrótu dla dwóch różnych wartości nvarchar było minimalne. Na podstawie moich badań w Internecie MD5 wydaje się najlepszy. Czy to prawda? MSDN mówi nam (link poniżej) o dostępnych algorytmach, ale nie ma opisu na jakich warunkach.

HASHBYTES (Transact-SQL)

Musimy połączyć dwie tabele na dwóch kolumnach nvarchar (max). Jak można sobie wyobrazić, wykonanie zapytania zajmuje dużo czasu. Pomyśleliśmy, że lepiej byłoby zachować wartość skrótu dla wszystkich danych nvarchar (max) i połączyć wartości hash zamiast wartości nvarchar (max), które są obiektami blob. Pytanie brzmi, który algorytm skrótu zapewnia unikalność, abyśmy nie mieli ryzyka posiadania jednej wartości skrótu dla więcej niż jednego nvarchar (maks.).

Niebo
źródło

Odpowiedzi:

18

HASHBYTESFunkcja trwa tylko do 8000 bajtów jako wejście. Ponieważ dane wejściowe są potencjalnie większe, duplikaty w zakresie pola, które zostanie zaszyfrowane , spowoduje kolizje, niezależnie od wybranego algorytmu. Ostrożnie zastanów się nad zakresem danych, które planujesz mieszać - użycie pierwszych 4000 znaków jest oczywistym wyborem, ale może nie być najlepszym wyborem dla twoich danych.

W każdym razie, z powodu tego, czym jest funkcja skrótu, nawet jeśli dane wejściowe mają 8000 bajtów lub mniej, jedynym sposobem na zapewnienie 100% poprawności wyników jest porównanie wartości podstawowych w pewnym momencie (czytaj: niekoniecznie najpierw ). Kropka.

Firma będzie decydować, czy wymagana jest 100% dokładność. Dzięki temu dowiesz się, że (a) porównanie wartości bazowej jest wymagane , lub (b) należy rozważyć nie porównując wartości podstawowe - ile dokładność powinien odbywać się pod kątem wydajności.

Podczas gdy kolizje skrótu są możliwe w unikalnym zestawie danych wejściowych, są one nieskończenie rzadkie, niezależnie od wybranego algorytmu. Cały pomysł użycia wartości skrótu w tym scenariuszu polega na skutecznym zawężeniu wyników łączenia do łatwiejszego do zarządzania zestawu, niekoniecznie natychmiastowego uzyskania końcowego zestawu wyników. Ponownie, dla 100% dokładności, nie może to być ostatni etap procesu. W tym scenariuszu nie stosuje się mieszania do celów kryptografii, więc algorytm taki jak MD5 będzie działał dobrze.

Bardzo trudno byłoby mi usprawiedliwić przejście na algorytm SHA-x dla celów „dokładności”, ponieważ jeśli firma zacznie wariować na temat minimalnych możliwości kolizji w MD5, istnieje szansa, że ​​również wystraszą się, że algorytmy SHA-x też nie są idealne. Muszą albo pogodzić się z niewielką niedokładnością, albo nakazać, aby zapytanie było w 100% dokładne i działało z powiązanymi implikacjami technicznymi. Podejrzewam, że jeśli CEO śpi lepiej w nocy, wiedząc, że użyłeś SHA-x zamiast MD5, cóż, dobrze; w tym przypadku nadal niewiele znaczy z technicznego punktu widzenia.

Mówiąc o wydajności, jeśli tabele są głównie do odczytu, a wynik łączenia jest często potrzebny, rozważ implementację widoku indeksowanego, aby wyeliminować potrzebę obliczania całego złączenia za każdym razem, gdy jest to wymagane. Oczywiście wymieniasz na to miejsce, ale może to być warte poprawy wydajności, szczególnie jeśli wymagana jest 100% dokładność.

Aby przeczytać więcej na temat indeksowania wartości długich ciągów, opublikowałem artykuł, który omawia przykład tego, jak to zrobić dla pojedynczej tabeli, i przedstawia rzeczy do rozważenia przy próbie pełnego scenariusza w tym pytaniu.

Jon Seigel
źródło
8

MD5 powinno być w porządku, a dane wyjściowe mogą być przechowywane w formacie binarnym (16). Prawdopodobieństwo kolizji (patrz paradoks urodzinowy ) jest nadal bardzo niskie, nawet przy dużej wielkości próbki fizycznej. Wyjście SHA-1 zajmuje 20 bajtów, a wyjście SHA-256 zajmuje 32 bajty. Jeśli nie masz tak dużej liczby zapisów, że prawdopodobieństwo kolizji urodzinowej staje się znaczące (fizycznie niemożliwe lub przynajmniej niepraktyczne przy obecnych technologiach sprzętowych), prawdopodobnie będzie w porządku.

ConcernedOfTunbridgeWells
źródło
0

Nie widziałem tego w odpowiedziach, ale według MSDN :

Począwszy od SQL Server 2016 (13.x), wszystkie algorytmy inne niż SHA2_256 i SHA2_512 są przestarzałe. Starsze algorytmy (niezalecane) będą nadal działać, ale spowodują zdarzenie wycofania.

Zadałem podobne pytanie, więc od Ciebie zależy, czy chcesz użyć przestarzałej funkcji, takiej jak MD5 (jeśli korzystasz z wersji 2016+). Możesz przeprowadzić testy, aby zobaczyć, jaka jest różnica w przechowywaniu i wydajności między MD5 a SHA2.

Gabe
źródło