microsoft excel 2010
Existe-t-il une fonction Excel pour créer une valeur de hachage ?
Je travaille avec un certain nombre de listes de données qui sont indexées par nom de document. Les noms de documents, bien que très descriptifs, sont assez encombrants si j'ai besoin de les visualiser (jusqu'à 256 octets, c'est beaucoup de biens immobiliers) et j'aimerais pouvoir créer un champ clé plus petit qui soit facilement reproductible au cas où j'en aurais besoin pour effectuer une VLOOKUP
à partir d'un autre workseet ou classeur.
Je pense qu'un hachage du titre qui serait unique et reproductible pour chaque titre serait le plus approprié. Existe-t-il une fonction disponible ou est-ce que je cherche à développer mon propre algorithme ?
Avez-vous des idées sur cette stratégie ou sur une autre ?
Vous n'avez pas besoin d'écrire votre propre fonction-d'autres l'ont déjà fait pour vous.
Par exemple, j'ai collecté et comparé cinq fonctions de hachage VBA sur cette réponse
Personnellement,j'utilise cette fonction VBA
- il est appelé avec
=BASE64SHA1(A1)
dans Excel après avoir copié la macro dans unmodule VBA - nécessite .NET car il utilise la bibliothèque "Microsoft MSXML" (avec liaison tardive).
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
Personnaliser la longueur du hachage
- le hachage est initialement une chaîne unicode de 28 caractères (sensible à la casse+caractères spéciaux).
- Vous personnalisez la longueur du hachage avec cette ligne :
Const cutoff As Integer = 5
- hachage de 4 chiffres=36 collisions en 6895 lignes=0,5 % de taux de collision
- hachage à 5 chiffres=0 collision en 6895 lignes=0 % de taux de collision
Il existe également des fonctions de hachage ( les trois fonctions CRC16 ) qui ne nécessitent pas .NET et n'utilisent pas de bibliothèques externes. Mais le hachage est plus long et produit plus de collisions.
Vous pouvez également simplement télécharger cet exemple de classeur et jouer avec les 5 implémentations de hachage. Comme vous le voyez, il y a une bonne comparaison sur la première feuille
Je ne me soucie pas beaucoup des collisions,mais j'avais besoin d'un pseudo-aléatoire faible de rangées basé sur un champ de chaîne de longueur variable.Voici une solution insensée qui a bien fonctionné :
=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)
Où Z2
est la cellule contenant la chaîne que vous souhaitez hacher.
Les "MOD" sont là pour empêcher le débordement vers la notation scientifique. 1009
est un nombre premier, peut utiliser n'importe quoi X pour que X*255 < max_int_size
. 10 est arbitraire ; utiliser n'importe quoi. Les valeurs "Else" sont arbitraires (chiffres de pi ici !) ; utiliser n'importe quoi. L'emplacement des caractères (1,3,5,7,9) est arbitraire ; utiliser n'importe quoi.