我想为Informix SQL中的列值计算某种哈希值或校验和值。
问题:
我们需要在测试数据中匿名化个人信息,并希望通过散列相关值来实现此目的,如:
UPDATE personal_data SET name=HASH(name), employee_no=HASH(employee_no)
我们希望使用哈希值,而不仅仅是固定值,因为它可以用于(通常)映射到不同结果的不同值,以及映射到相同结果的相同值。这使得仍然可以对测试数据进行比较(例如,可能有几个记录具有相同的employee_no,并且保留该信息很有用。)
大多数DBMS都有某种散列函数(PostgreSQL和MySQL有MD5(),Oracle有DBMS_UTILITY.GET_HASH_VALUE),但我找不到任何Informix(Informix IDS 9)。这是一个缺少的功能吗?
答案 0 :(得分:1)
sleske,
几年前,我编写了一个T-SQL函数来计算SHA-1哈希值。如果这对您有用,也许您可以为Informix重写我的功能。 This newsgroup thread有关于其局限性的更多信息。
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), 32-@N)
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) | ((@2_32-@B-1) & @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
答案 1 :(得分:1)
IDS没有任何哈希函数作为内置函数公开,AFAICR。
假设您使用的是IBM Informix Dynamic Server(IDS)版本10.00或更高版本(不支持早期版本 - 嗯,直到2009-09-30支持7.31,但不支持更高版本),那么可以创建UDR (用户定义的例程)完成这项工作。这并非难以置信 - 但这也不是一件容易的事。
答案 2 :(得分:1)
您可以使用ENCRYPT_TDES。加密字符串比原始字符串长得多,但这不应该是一个问题 - 值将被截断。加密+截断应该得到类似于哈希值的结果。 我不太确定9.40中是否有加密,可能不是。 在这种情况下,您必须在客户端上计算哈希值。
答案 3 :(得分:0)
如果您可以更改表结构,则可以使用WITH VERCOLS选项。见Using the WITH VERCOLS Option。 简而言之:此选项为您提供了2个额外的隐藏列:最初插入行的校验和以及行上的更改(更新)数。