2009-09-25 9 views
2

Je voudrais calculer une sorte de valeur de hachage ou de somme de contrôle pour une valeur de colonne dans Informix SQL.Calculer la valeur de hachage/somme de contrôle dans Informix SQL

Le problème:

Nous devons anonymiser les renseignements personnels dans les données de test, et je voudrais le faire en hachant les valeurs pertinentes, comme dans:

UPDATE personal_data SET name=HASH(name), employee_no=HASH(employee_no) 

Nous voulons utiliser un hachage, plutôt qu'une simple valeur fixe, car il est utile que différentes valeurs soient (généralement) mappées sur des résultats différents et que les mêmes valeurs soient mappées au même résultat. Cela permet de faire encore des comparaisons sur les données de test (par exemple, il est possible d'avoir plusieurs enregistrements avec le même employé_no, et il est utile de conserver cette information).

La plupart des SGBD ont une sorte de fonction de hachage (PostgreSQL et MySQL ont MD5(), Oracle a DBMS_UTILITY.GET_HASH_VALUE), mais je n'ai rien trouvé pour Informix (Informix IDS 9). Est-ce une fonctionnalité manquante?

+0

Quelle version d'IDS utilisez-vous? –

+0

Informix IDS 9 (c'est dans la question :-)) – sleske

Répondre

1

IDS n'a aucune des fonctions de hachage exposées comme fonctions intégrées, AFAICR. En supposant que vous utilisez IBM Informix Dynamic Server (IDS) version 10.00 ou ultérieure (les versions antérieures ne sont pas supportées - bien, 7.31 est supporté jusqu'au 2009-09-30, mais pas au-delà), alors il est possible de créer un UDR (routine définie par l'utilisateur) qui fait le travail. Ce n'est pas incroyablement difficile - mais ce n'est pas non plus trivial.

+0

Merci, c'est ce que je craignais. Je devrais probablement écrire un UDR ou un programme d'aide pour faire le travail :-(. – sleske

+0

Je peux vous suggérer que vous considérez soigneusement si votre UDR devrait s'appeler 'MD5()' ou si ce serait mieux pour l'appeler, disons, 'app_hash()' de sorte que si/quand IDS acquiert une fonction MD5 (ou SHA-1, ou SHA-256, ou ...), vous ne rencontrerez pas de problème de nommage? peut risquer que IDS fournisse une fonction avec la même signature que votre UDR, mais que la sortie sera incompatible à l'avenir –

+0

@Jonathan: Bon point, je l'appellerais probablement myHash ou similaire, parce que je ne sais pas se soucient vraiment de l'algorithme, j'ai juste besoin d'un hachage.Quoi qu'il en soit, le faire en tant que programme externe sera probablement plus simple, car je connais peu les UDR (et nous ne les utilisons pas actuellement). – sleske

1

sleske,

Il y a quelques années, je l'ai écrit une fonction T-SQL pour calculer SHA-1. Si cela fonctionne pour vous, vous pouvez peut-être retravailler ma fonction pour Informix. This newsgroup thread a un peu plus d'informations sur ses limites.

create function S( 
    @N int, 
    @x bigint 
) returns binary(4) as begin 
    declare @two_N bigint 
    set @two_N = power(cast(2 as bigint), @N) 
    declare @two_32_N bigint 
    set @two_32_N = power(cast(2 as bigint), [email protected]) 
    return cast(@x%@two_32_N*@two_N + @x/@two_32_N as binary(4)) 
end 
go 
create function f( 
    @t bigint, 
    @B bigint, 
    @C bigint, 
    @D bigint 
) returns bigint as begin 
    declare @2_32 bigint set @2_32 = power(cast(2 as bigint),32) 
    if @t between 0 and 19 
    return (@B & @C) | ((@[email protected]) & @D) 
    if @t between 20 and 39 
    return @B^@C^@D 
    if @t between 40 and 59 
    return (@B & @C) | (@B & @D) | (@C & @D) 
    return @B^@C^@D 
end 
go 
create function SHA1 ( 
    @s varchar(55) 
) returns binary(20) as begin 
    declare @b varbinary(55) 
    set @b = cast(@s as varbinary(55)) 
    declare @zeros binary(64) 
    set @zeros = 0x 
    declare @padded binary(64) 
    set @padded = 
    @b + 0x80 + substring(@zeros,1,55-datalength(@b)) 
     + cast(8*datalength(@b) as binary(8)) 
    declare @H5 binary(20) 
    set @H5 = 0x67452301EFCDAB8998BADCFE10325476C3D2E1F0 
    declare @K4 binary(16) 
    set @K4 = 0x5A8279996ED9EBA18F1BBCDCCA62C1D6 
    declare @ABCDE binary(20) set @ABCDE = @H5 
    declare @W80 varbinary(320) set @W80 = @padded 
    declare @TEMP binary(4) set @TEMP = 0x 
    declare @2_32 bigint set @2_32 = power(cast(2 as bigint),32) 
    declare @t int 
    set @t = 16 
    while @t < 80 begin 
    set @W80 = @W80 + 
     dbo.S(1,cast(substring(@W80,(@t-3)*4+1,4) as bigint) 
      ^cast(substring(@W80,(@t-8)*4+1,4) as bigint) 
      ^cast(substring(@W80,(@t-14)*4+1,4) as bigint) 
      ^cast(substring(@W80,(@t-16)*4+1,4) as bigint)) 
    set @t = @t + 1 
    end 
    set @t = 0 
    while @t < 80 begin 
    set @TEMP = cast((cast(dbo.S(5,substring(@ABCDE,1,4)) as bigint) 
      + dbo.f(@t,substring(@ABCDE,5,4) 
        ,substring(@ABCDE,9,4) 
        ,substring(@ABCDE,13,4)) 
      + cast(substring(@ABCDE,17,4) as bigint) 
      + cast(substring(@W80,4*@t+1,4) as bigint) 
      + cast(substring(@K4,4*(@t/20)+1,4) as bigint))%@2_32 as 
binary(4)) 
    set @ABCDE = @TEMP+substring(@ABCDE,1,4) 
        +dbo.S(30,substring(@ABCDE,5,4)) 
        +substring(@ABCDE,9,8) 
    set @t = @t + 1 
    end 
    set @H5 
    = cast((cast(substring(@H5, 1,4) as bigint) + cast(substring(@ABCDE, 1,4) 
as bigint))% @2_32 as binary(4)) 
    + cast((cast(substring(@H5, 5,4) as bigint) + cast(substring(@ABCDE, 5,4) 
as bigint))% @2_32 as binary(4)) 
    + cast((cast(substring(@H5, 9,4) as bigint) + cast(substring(@ABCDE, 9,4) 
as bigint))% @2_32 as binary(4)) 
    + cast((cast(substring(@H5,13,4) as bigint) + cast(substring(@ABCDE,13,4) 
as bigint))% @2_32 as binary(4)) 
    + cast((cast(substring(@H5,17,4) as bigint) + cast(substring(@ABCDE,17,4) 
as bigint))% @2_32 as binary(4)) 
    return @H5 
end 
+0

Intéressant! Il y aurait beaucoup de travail à faire pour traduire cela en Informix - les opérations au niveau du bit ne sont pas directement supportées, par exemple. –

+0

Je ne pense pas qu'il soit logique pour moi de ré-implémenter SHA-1. Si je ne peux pas le faire à l'intérieur d'Informix, je vais probablement écrire un programme externe pour le faire: - /. – sleske

0

Si vous pouvez modifier la structure de la table, vous pouvez utiliser l'option WITH VERCOLS. Voir Using the WITH VERCOLS Option. En bref: cette option vous donne 2 colonnes cachées supplémentaires: somme de contrôle pour la ligne insérée à l'origine et le nombre de changements (mises à jour) sur la ligne.

+0

Intéressant. Mais je ne vois pas comment cela pourrait m'aider, car il semble générer une somme de contrôle pour toute la ligne, pas pour la valeur dans une colonne. – sleske

1

Vous pouvez utiliser ENCRYPT_TDES. La chaîne cryptée est beaucoup plus longue que l'original mais cela ne devrait pas poser de problème - la valeur sera tronquée. Cryptage + troncature devrait obtenir un résultat similaire à la valeur de hachage. Je ne suis pas tout à fait sûr si le cryptage est disponible en 9.40, probablement pas. Dans ce cas, vous devez calculer la valeur de hachage sur le client.

+0

Bonne solution. Oui, le cryptage + troncature le ferait probablement. Il est répertorié comme une nouvelle fonctionnalité dans la liste des fonctionnalités pour IDS 10.0, donc malheureusement, il n'est probablement pas disponible dans 9.40, ce qui est l'endroit où j'en aurais besoin: - /. – sleske

+0

BTW: Bienvenue sur stackoverflow. Votre première réponse est un bon début :-). – sleske

Questions connexes