2

我想为 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)的任何东西。这是缺少的功能吗?

4

4 回答 4

1

斯莱斯克,

几年前,我编写了一个 T-SQL 函数来计算 SHA-1 哈希值。如果这对您有用,也许您可​​以为 Informix 重新设计我的功能。这个新闻组线程有更多关于它的限制的信息。

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 
于 2009-09-25T15:10:52.053 回答
1

IDS 没有任何作为内置函数 AFAICR 公开的散列函数。

假设您使用的是 IBM Informix Dynamic Server (IDS) 版本 10.00 或更高版本(不支持早期版本 - 嗯,在 2009-09-30 之前支持 7.31,但不超过),那么可以创建 UDR(用户-定义的例程)完成这项工作。这不是难以置信的困难——但也不是微不足道的。

于 2009-09-27T03:33:13.723 回答
1

您可以使用ENCRYPT_TDES。加密字符串比原始字符串长得多,但这应该不是问题 - 值将被截断。加密+截断应该得到类似于哈希值的结果。我不太确定 9.40 中是否可以使用加密,可能不是。在这种情况下,您必须在客户端计算哈希值。

于 2009-12-10T21:38:59.967 回答
0

如果您可以更改表结构,那么您可以使用 WITH VERCOLS 选项。请参阅使用 WITH VERCOLS 选项。简而言之:此选项为您提供了 2 个额外的隐藏列:原始插入行的校验和以及该行的更改(更新)数量。

于 2009-12-10T15:03:21.707 回答