Вам не нужно писать свою собственную функцию - другие уже сделали это для вас.
Например, я собрал и сравнил пять хеш-функций VBA в этом ответе
Лично я использую эту функцию VBA
- вызывается
=BASE64SHA1(A1)
в Excel после копирования макроса в модуль VBA
- требует .NET, так как использует библиотеку "Microsoft MSXML" (с поздним связыванием)
Public Function BASE64SHA1(ByVal sTextToHash As String)
Dim asc As Object
Dim enc As Object
Dim TextToHash() As Byte
Dim SharedSecretKey() As Byte
Dim bytes() As Byte
Const cutoff As Integer = 5
Set asc = CreateObject("System.Text.UTF8Encoding")
Set enc = CreateObject("System.Security.Cryptography.HMACSHA1")
TextToHash = asc.GetBytes_4(sTextToHash)
SharedSecretKey = asc.GetBytes_4(sTextToHash)
enc.Key = SharedSecretKey
bytes = enc.ComputeHash_2((TextToHash))
BASE64SHA1 = EncodeBase64(bytes)
BASE64SHA1 = Left(BASE64SHA1, cutoff)
Set asc = Nothing
Set enc = Nothing
End Function
Private Function EncodeBase64(ByRef arrData() As Byte) As String
Dim objXML As Object
Dim objNode As Object
Set objXML = CreateObject("MSXML2.DOMDocument")
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeBase64 = objNode.text
Set objNode = Nothing
Set objXML = Nothing
End Function
Настройка длины хеша
- изначально хеш - это строка в Unicode длиной 28 символов (с учетом регистра + специальные символы)
- Вы настраиваете длину хеша с помощью этой строки:
Const cutoff As Integer = 5
- Хэш из 4 цифр = 36 столкновений в 6895 строках = частота столкновений 0,5%
- Хэш из 5 цифр = 0 коллизий в 6895 строках = 0% коллизий
Есть также хэш-функции ( все три функции CRC16 ), которые не требуют .NET и не используют внешние библиотеки. Но хэш длиннее и производит больше коллизий.
Вы также можете просто скачать этот пример рабочей книги и поиграть со всеми 5 реализациями хешей. Как видите, на первом листе есть хорошее сравнение
#NAME?
. Просмотреть код> вырезать и вставить код в новое окно - в правильном рабочем листе в навигаторе> сохранить как рабочий лист с поддержкой макросов> закрыть и вернуться в Excel ... что-нибудь еще мне не хватает? Нужно ли как-то его скомпилировать?cutoff
параметризованный и необязательный параметр с другим значением по умолчанию, переместив его в список параметров функцииPublic Function BASE64SHA1(ByVal sTextToHash As String, Optional ByVal cutoff As Integer = 8)
и удалив объявление внутри функции.Меня не очень волнуют коллизии, но мне нужен слабый псевдослучайный ряд строк, основанный на строковом поле переменной длины. Вот одно безумное решение, которое сработало хорошо:
Где
Z2
находится ячейка, содержащая строку, которую вы хотите хэшировать.«MOD» предназначены для предотвращения перетекания в научную нотацию.
1009
простое число, может использовать что угодно X, так что X * 255 <max_int_size
. 10 произвольно; использовать что угодно. «Остальные» значения являются произвольными (цифры пи здесь!); использовать что угодно. Расположение символов (1,3,5,7,9) произвольно; использовать что угодно.источник
Для относительно небольшого списка вы можете создать скремблер (хэш-функцию бедняка), используя встроенные функции Excel.
Например
Здесь A1 и B1 содержат случайную начальную букву и длину строки.
Немного возиться и проверять, и в большинстве случаев вы можете получить работоспособный уникальный идентификатор довольно быстро.
Как это работает : формула использует первую букву строки и фиксированную букву, взятую из средней строки, и использует LEN () в качестве «функции раздувания», чтобы уменьшить вероятность столкновений.
ПРЕДУПРЕЖДЕНИЕ : это не хеш, но когда вам нужно что-то сделать быстро и проверить результаты, чтобы убедиться, что нет столкновений, это работает довольно хорошо.
Редактировать: если ваши строки должны иметь переменную длину (например, полные имена), но извлекаются из записи базы данных с полями фиксированной ширины, вы захотите сделать это так:
так что длины являются значимым скремблером.
источник
Я использую это, что дает довольно хорошие результаты, предотвращая конфликты без необходимости каждый раз запускать скрипт. Мне нужно было значение от 0 до 1.
Он выбирает буквы по всей строке, принимает значение каждой из этих букв, добавляет значение (чтобы одни и те же буквы в разных местах не давали одинаковые результаты), умножает / делит каждое и запускает функцию COS для общего количества.
источник
Вы можете попробовать это. Запустите псевдо # на двух столбцах:
Где A1 и B1 хранят случайные семена, введенные вручную: 0
источник
Насколько мне известно, в Excel нет встроенной хэш-функции - вам нужно будет создать ее как пользовательскую функцию в VBA.
Тем не менее, обратите внимание, что для вашей цели я не думаю, что использование хэша является обязательным или действительно выгодным!
VLOOKUP
будет работать с 256 байтами так же хорошо, как с меньшим хешем. Конечно, это может быть чуть-чуть медленнее, точно настолько маленьким, что это неизмеримо. А затем добавление значений хеш-функции требует больше усилий - и для Excel ...источник
title
в моей замороженной левой панели ...