No necesita escribir su propia función; otros ya lo hicieron por usted.
Por ejemplo, recopilé y comparé cinco funciones hash de VBA en esta respuesta de stackoverflow
Personalmente uso esta función VBA
- se llama con
=BASE64SHA1(A1)
en Excel después de copiar la macro a un módulo VBA
- requiere .NET ya que usa la biblioteca "Microsoft MSXML" (con enlace tardío)
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
Personalizar la longitud del hash
- el hash inicialmente es una cadena unicode de 28 caracteres de longitud (mayúsculas y minúsculas + caracteres especiales)
- Personaliza la longitud del hash con esta línea:
Const cutoff As Integer = 5
- Hash de 4 dígitos = 36 colisiones en 6895 líneas = 0.5% de tasa de colisión
- Hash de 5 dígitos = 0 colisiones en 6895 líneas = 0% tasa de colisión
También hay funciones hash ( las tres funciones CRC16 ) que no requieren .NET y no usan bibliotecas externas. Pero el hash es más largo y produce más colisiones.
También puede descargar este libro de trabajo de ejemplo y jugar con las 5 implementaciones de hash. Como veis hay una buena comparación en la primera hoja
#NAME?
. Ver código> cortar y pegar código en una nueva ventana: dentro de la hoja de trabajo correcta en el navegador> guardar como hoja de trabajo habilitada para macros> cerrar y volver a sobresalir ... ¿me falta algo más? ¿Necesito compilarlo de alguna manera?cutoff
parámetro sea opcional y opcional con un valor predeterminado diferente moviéndolo hacia arriba a la lista de parámetros de FunciónPublic Function BASE64SHA1(ByVal sTextToHash As String, Optional ByVal cutoff As Integer = 8)
y eliminando la declaración dentro de la función.No me importan mucho las colisiones, pero necesitaba un pseudoaleatorizador débil de filas basado en un campo de cadena de longitud variable. Aquí hay una solución loca que funcionó bien:
¿Dónde
Z2
está la celda que contiene la cadena que quieres hash?Los "MOD" están ahí para evitar el desbordamiento a la notación científica.
1009
es primo, podría usar cualquier cosa X para que X * 255 <max_int_size
. 10 es arbitrario; usa cualquier cosa. Los valores "Else" son arbitrarios (¡dígitos de pi aquí!); usa cualquier cosa. La ubicación de los caracteres (1,3,5,7,9) es arbitraria; usa cualquier cosa.fuente
Para una lista razonablemente pequeña, puede crear un codificador (función hash del pobre) usando las funciones integradas de Excel.
P.ej
Aquí A1 y B1 contienen una letra de inicio aleatoria y una longitud de cadena.
Un poco de manipulación y comprobación y, en la mayoría de los casos, puede obtener una identificación única viable rápidamente.
Cómo funciona : la fórmula usa la primera letra de la cadena y una letra fija tomada de la mitad de la cadena y usa LEN () como una 'función de abanico' para reducir la posibilidad de colisiones.
PRUEBA : esto no es un hash, pero cuando necesitas hacer algo rápidamente y puedes inspeccionar los resultados para ver que no hay colisiones, funciona bastante bien.
Editar: si sus cadenas deben tener longitudes variables (por ejemplo, nombres completos) pero se extraen de un registro de base de datos con campos de ancho fijo, querrá hacerlo así:
para que las longitudes sean un codificador significativo.
fuente
Estoy usando esto, que da muy buenos resultados al evitar conflictos sin necesidad de ejecutar un script cada vez. Necesitaba un valor entre 0 y 1.
Selecciona letras de la cadena, toma el valor de cada una de esas letras, agrega un valor (para evitar que las mismas letras en diferentes lugares den los mismos resultados), multiplica / divide cada una y ejecuta una función COS sobre el total.
fuente
Puedes probar esto. Ejecute un Pseudo # en dos columnas:
Donde A1 y B1 almacenan semillas aleatorias ingresadas manualmente: 0
fuente
Que yo sepa, no hay una función hash integrada en Excel: necesitaría crear una como una función definida por el usuario en VBA.
Sin embargo, tenga en cuenta que para su propósito, ¡no creo que usar un hash sea obligatorio o realmente ventajoso!
VLOOKUP
funcionará igual de bien en 256 bytes que en un hash más pequeño. Claro, puede ser un poco más lento, un bit que es tan pequeño que es inconmensurable. Y luego agregar los valores hash es más esfuerzo para usted, y para Excel ...fuente
title
en mi panel izquierdo congelado ...