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)

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.