La guía paso a paso o código que encontrarás en este artículo es la resolución más rápida y efectiva que hallamos a tu duda o problema.
Solución:
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 de VBA
- se llama con
=BASE64SHA1(A1)
en Excel después de copiar el macro a un VBA módulo - 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
Personalización de la longitud del hash
- el hash inicialmente es un Unicode de 28 caracteres de largo string (sensible a mayúsculas y minúsculas + caracteres especiales)
- Personalizas 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 simplemente descargar este libro de trabajo de ejemplo y jugar con las 5 implementaciones de hash. Como veis hay una buena comparativa en la primera hoja
No me importan mucho las colisiones, pero necesitaba un pseudoaleatorizador débil de filas basado en una longitud variable string campo. Aquí hay una solución loca que funcionó bien:
=MOD(MOD(MOD(MOD(MOD(IF(LEN(Z2)>=1,CODE(MID(Z2,1,1))+10,31),1009)*IF(LEN(Z2)>=3,CODE(MID(Z2,3,1))+10,41),1009)*IF(LEN(Z2)>=5,CODE(MID(Z2,5,1))+10,59),1009)*IF(LEN(Z2)>=7,CODE(MID(Z2,7,1))+10,26),1009)*IF(LEN(Z2)>=9,CODE(MID(Z2,9,1))+10,53),1009)
Dónde Z2
es la celda que contiene el string quieres hacer 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
Para una lista razonablemente pequeña, puede crear un codificador (función hash del hombre pobre) utilizando las funciones integradas de Excel.
P.ej
=CODE(A2)*LEN(A2) + CODE(MID(A2,$A$1,$B$1))*LEN(MID(A2,$A$1,$B$1))
Aquí A1 y B1 tienen una letra inicial aleatoria y string longitud.
Un poco de manipulación y verificación y, en la mayoría de los casos, puede obtener una identificación única viable con bastante rapidez.
Cómo funciona: La fórmula utiliza la primera letra de la string y una letra fija sacada de mediados destring y usa LEN() como una ‘función de abanico’ para reducir la posibilidad de colisiones.
ADVERTENCIA: esto es no un hash, pero cuando necesita hacer algo rápidamente y puede inspeccionar los resultados para ver que no haya 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í:
=CODE(TRIM(C8))*LEN(TRIM(C8))
+CODE(MID(TRIM(C8),$A$1,1))*LEN(MID(TRIM(C8),$A$1,$B$1))
para que las longitudes sean un codificador significativo.
valoraciones y comentarios
Agradecemos que quieras añadir valor a nuestro contenido informacional colaborando tu veteranía en las reseñas.