【问题标题】:Convert SQL result from Hash to Varchar将 SQL 结果从 Hash 转换为 Varchar
【发布时间】:2020-12-09 03:26:07
【问题描述】:

我在一个散列的 SQL 表中有一些数据,并试图将这些变量转换回字符串,但是我得到的所有内容都是乱码。

我已经尝试了有关 Stack Overflow 的所有建议,包括删除所有连续的双零“00”。

我不知道未经哈希处理的变量是什么样的,但我认为它将是一个字符串变量。我们怎么会知道从哪里开始确定对该字段应用哪种哈希?

非常感谢任何帮助或指导。

到目前为止,我的尝试是:

SELECT CASE WHEN LEN(0x00007041673F000000007041B2060000) > 0 THEN
    convert(varchar(max),     
        convert(varbinary(max),
            REPLACE(
            convert(varchar(max),0x00007041673F000000007041B2060000, 1)
            ,'00',''
            )
        ,1)
    ,1)
    ELSE '' END
    
  ,CONVERT(varbinary(64),0x00007041673F000000007041B2060000, 1)
  ,CONVERT(varchar(64), 0x00007041673F000000007041B2060000, 1)
  ,CONVERT(varchar(64), 0x00007041673F000000007041B2060000, 2)


--Other Hash Variables-
--0x00007041673F000000007041B2060000
--0x0000C84271EB0000
--0x0000C842683F0000
--0x0000C842693F0000
--0x0000C842703F00000000C842775A0200
--0x0000A041873F00000000A041F9050000
--0x0000C842264000000000C842F04F0100
--0x000034427C400000000034426E4A0000

编辑 - 还尝试在 SQL 上进行 BASE64 解码 - https://dba.stackexchange.com/questions/191273/decode-base64-string-natively-in-sql-server

SELECT 
    CONVERT
    (
        VARCHAR(MAX), 
        CAST('' AS XML).value('xs:base64Binary(sql:column("BASE64_COLUMN"))', 'VARBINARY(MAX)')
    ) AS RESULT
FROM
    (
        SELECT '0x00007041673F000000007041B2060000' AS BASE64_COLUMN
    ) A

【问题讨论】:

  • 没有其他人可以告诉您散列是什么 - 您需要访问执行散列的代码。不过要尝试的一件事是假设 base64 编码。
  • A hash function “是可用于将任意大小的数据映射到固定大小值的任何函数。”它本质上不是一个可逆的过程,也不能保证结果是唯一的。当使用给定算法进行哈希处理时,您的中间名首字母和 Encyclopædia Galactica 可能会碰巧生成值0xDEADC0DE。尽管您可能能够从散列值转到 a 值,但您不能确定它是原始值。
  • 大部分二进制值都是 16 字节,它们可以只是唯一标识符吗? select cast(0x00007041673F000000007041B2060000 as uniqueidentifier)

标签: sql sql-server tsql hex ascii


【解决方案1】:

如果这确实是一个哈希值,则没有实际机会将该值恢复为其值。

但是,看看你的值,我怀疑这些真的是哈希值。获得如此接近的二进制表示是非常不寻常的。尝试对任何值使用任何散列函数。你不会得到如此相似的结果...

在不了解您的需求的情况下,您可能会尝试将二进制值视为任何(16 字节?)类型或较小类型的链。这里我使用BIGINT(两个 8 字节值),您可以尝试UNIQUEIDENTIFIER,或者您可以将其视为 16 个 1 字节值链、8 个 2 字节值链或任何其他可行的解释.

DECLARE @tbl TABLE(YourBinary VARBINARY(MAX));
INSERT INTO @tbl VALUES
--Other Hash Variables-
 (0x00007041673F000000007041B2060000)
,(0x0000C84271EB0000                )
,(0x0000C842683F0000                )
,(0x0000C842693F0000                )
,(0x0000C842703F00000000C842775A0200)
,(0x0000A041873F00000000A041F9050000)
,(0x0000C842264000000000C842F04F0100)
,(0x000034427C400000000034426E4A0000);

SELECT DATALENGTH(YourBinary) AS TheByteLength
      ,CAST(YourBinary AS UNIQUEIDENTIFIER) AS CastedToGuid
      ,A.*
      ,CAST(A.Left8 AS BIGINT) AS Left8_Bigint
      ,CAST(A.Right8 AS BIGINT) AS Right8_Bigint
FROM @tbl
CROSS APPLY(SELECT CONVERT(BINARY(8),LEFT(YourBinary,8),0) AS Left8
                  ,CASE WHEN DATALENGTH(YourBinary)=16 THEN CONVERT(BINARY(8),RIGHT(YourBinary,8),0) END AS Right8) A;

一个猜测:这可能是两个数字的组合键。可能是二进制组合中的租户和表键。很明显,这些值由非常相似的数字组成。那些有 16 个字节的包含相当接近的值。

Left8_Bigint    Right8_Bigint
123426207367168 123427461922816
220187704623104 NULL
220187542355968 NULL
220187559133184 NULL
220187676573696 220187795784192
176203302371328 176205211172864
220186435125248 220189825106176
57460157054976  57459922829312

告诉我们更多关于您的问题的背景可能会有所帮助...

更新

将此作为 4 字节整数值链返回相当有趣的结果:

SELECT CAST(Byte4_1 AS INT)
      ,CAST(Byte4_2 AS INT)
      ,CAST(Byte4_3 AS INT)
      ,CAST(Byte4_4 AS INT)
FROM @tbl
CROSS APPLY(SELECT CONVERT(BINARY(4),LEFT(YourBinary,4),0) AS Byte4_1
                  ,CONVERT(BINARY(4),SUBSTRING(YourBinary,5,4),0) AS Byte4_2
                  ,CONVERT(BINARY(4),SUBSTRING(YourBinary,9,4),0) AS Byte4_3
                  ,CONVERT(BINARY(4),SUBSTRING(YourBinary,13,4),0) AS Byte4_4) A;

结果

int1    int2        int3    int4
28737   1732182016  28737   -1308229632
51266   1911226368  0       0
51266   1748959232  0       0
51266   1765736448  0       0
51266   1883176960  51266   2002387456
41025   -2025914368 41025   -117112832
51266   641728512   51266   -263257856
13378   2084569088  13378   1850343424

int1 和 int3 似乎是相同的值。这指向任何类型的组合键...

【讨论】:

  • 非常感谢您 - 这对您有很大帮助。我们正在尝试从记录不充分的历史数据库中提取数据,其中存储了一个重要的标志。 int1 和 int3 字段实际上确实与一个单独的表相关,在这一点上,我觉得 int2 和 int4 指示标志与连接的关系。
  • @Tiki_Tiki 啊,有趣。我会将其作为 8 个 2 字节值的块进行调查。 int1a 为 0,int1b 就是上面的 int1。我会对 int2a 特别感兴趣,而 int2b 似乎是 0。试试这个?
【解决方案2】:

如果它真的是一个哈希值,那么你将无法将它转换回来。
大多数散列算法的设计是在有限时间内逆转该过程是不可行的,即解密数据的过程与破解某人的密码同样昂贵。

您可以在下面的讨论中找到更多详细信息: https://security.stackexchange.com/questions/11717/why-are-hash-functions-one-way-if-i-know-the-algorithm-why-cant-i-calculate-t

【讨论】:

  • 感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多