2010-04-21 18 views
3

J'écris une application C# qui permet aux utilisateurs de stocker des emails dans une base de données MS SQL Server. Plusieurs fois, plusieurs utilisateurs seront copiés sur un e-mail d'un client. Si tous essaient d'ajouter le même courrier électronique à la base de données, je veux m'assurer que l'email n'est ajouté qu'une fois. MD5 vient à l'esprit comme un moyen de le faire. Je n'ai pas besoin de m'inquiéter de la falsification malveillante, seulement pour m'assurer que le même courriel correspondra au même hachage et qu'aucun e-mail avec un contenu différent ne sera mappé au même hachage. Ma question se résume à la façon dont on combinerait plusieurs champs dans une valeur de hachage MD5 (ou autre). Certains de ces champs auront une seule valeur par e-mail (par exemple, objet, corps, adresse e-mail de l'expéditeur) alors que d'autres auront plusieurs valeurs (nombre variable de pièces jointes, destinataires). Je souhaite développer un moyen d'identifier de manière unique un e-mail indépendant de la plateforme et de la langue (non basé sur la sérialisation). Aucun conseil?Identifiant unique pour un email

+0

Avez-vous étudié les solutions existantes qui implémentent cette fonctionnalité? L'approche est appelée déduplication et est mise en œuvre par exemple. dans Symantec Vault: http://www.symantec.com/business/enterprise-vault – Marek

Répondre

2

Quel est le volume des e-mails Avez-vous sur l'archivage? Si vous ne vous attendez pas à ce que l'archive nécessite plusieurs téraoctets, je pense que c'est une optimisation prématurée.

Étant donné que chaque champ peut être représenté sous la forme d'une chaîne ou d'un tableau d'octets, peu importe le nombre de valeurs qu'il contient, il ressemble à une fonction de hachage. Il suffit de les hacher tous ensemble et vous obtiendrez un identifiant unique.

EDIT exemple de psuedocode

# intialized the hash object 
hash = md5() 

# compute the hashes for each field 
hash.update(from_str) 
hash.update(to_str) 
hash.update(cc_str) 
hash.update(body_str) 
hash.update(...) # the rest of the email fields 

# compute the identifier string 
id = hash.hexdigest() 

Vous obtiendrez la même sortie si vous remplacez toute la mise à jour appelle avec

# concatenate all fields and hash 
hash.update(from_str + to_str + cc_str + body_str + ...) 

Comment extraire les chaînes et l'interface varie en fonction de votre demande , langage et api.

Peu importe que des clients de messagerie différents puissent produire une mise en forme différente pour certains champs lorsqu'ils reçoivent la même entrée, cela vous donnera un hachage unique à l'e-mail d'origine. Pourquoi ne pas simplement hacher le message brut?

+3

Je vois un défaut majeur avec ce pseudo-code. Pour simplifier, supposons qu'il n'y a que deux champs, string1 et string2. Avec votre code psuedocode, {string1 = "foo", string2 = "bar"} et {string1 = "foob", string2 = "ar"} donneraient le même hachage. Peut-être que cela peut être résolu en hachant les sommes des hachages individuels? – Skywalker

+1

Un hachage n'est pas garanti unique. Différentes entrées peuvent - et vont - générer le même hachage. Si les hachages correspondent, vous devriez faire une comparaison de contenu de toute façon. Vous avez tendance à utiliser des seaux de hachage, et chaque seau contient tous les messages avec ce hachage. (dans une structure de table ce serait 2 tables, une (hash = unique) et une (id = unique, clé étrangère à hash non unique, le message + en-têtes – extraneon

+1

Utilisation d'une fonction de hachage cryptographique avec une grande valeur de hachage (comme MD5 avec ses valeurs de hachage 128 bits), vous pouvez pratiquement garantir que vous n'aurez pas de collisions de hachage.Le problème avec ce régime est qu'il produit des cas facilement prévisibles où les hachages entrent en collision – Skywalker

1

Avez-vous regardé quelques autres en-têtes comme (dans mon courrier, OS X Mail):

X-Universally-Unique-Identifier: 82d00eb8-2a63-42fd-9817-a3f7f57de6fa 
Message-Id: <[email protected]> 

Au moins, le message-Id est nécessaire. Ce champ pourrait bien être le même pour le même mailing (envoyer à plusieurs destinataires). Ce serait plus efficace que le hachage.

pas la réponse à la question, mais peut-être la réponse au problème :)

+0

Le problème avec cette approche est qu'elle dépend du client de messagerie. Je veux trouver une stratégie qui fonctionnera tant que vous connaissez l'heure d'envoi, l'adresse email de l'expéditeur, le sujet, le corps, les destinataires et les pièces jointes – Skywalker

+0

Les en-têtes internet peuvent être absents si un email a été envoyé via MS Exchange Server. Donc, ce n'est pas une technique suggérée.C'est bien en principe mais ça ne marchera pas dans le monde réel. – LaBracca

1

Il code déjà tous les champs pertinents à l'exception de l'expéditeur et du destinataire de l'enveloppe, et vous pouvez les ajouter vous-même avant le hachage. Il contient également toutes les pièces jointes, le corps entier du message, etc, et c'est une représentation naturelle et facile. Il ne souffre pas non plus des collisions de hachage facilement générées par la proposition de mikerobi.

+0

Malheureusement, j'ai menti quand j'ai dit que je veux que ce soit indépendant de la plateforme. Il doit au minimum soutenir Outlook qui, par la sagesse infinie de Microsoft, ne stocke pas le message brut – Skywalker