需要 SQL 雪花中的服务器 HASHBYTES SHA1 等效输出
Need SQL Server HASHBYTES SHA1 equivalent output in snowflake
我需要一个 SQL 来自 Snowflake 的服务器等效 Hashbytes SHA1 输出
SQL 服务器:
select hashbytes('sha1',cast('214163915155286000' as varchar(18)))*1
或
select cast(hashbytes('sha1',cast('214163915155286000' as varchar(18))) as int)
SQL 服务器输出:
2143072043
我可以使用下面的方法从 snowflake 生成 hashbytes 输出,但现在我无法将它转换成数值
select to_char(to_binary(sha1('214163915155286000'), 'hex'), 'base64') as Result;
部分雪花输出:
N0VDrFqYkK+M2GPrfJjnRn+8rys=
Snowflake 的预期输出:
2143072043
仅供参考 - 我在此处尝试了 SQL 服务器代码
所以在 SQL 服务器中进行少量播放。
select '214163915155286000' as s,
hashbytes('sha1', '214163915155286000') as h,
cast(hashbytes('sha1', '214163915155286000') as int) as i
;
给出:
s, 214163915155286000
h, 0x374543AC5A9890AF8CD863EB7C98E7467FBCAF2B
i, 2143072043
所以我的 SQL 和你的一样,作为一个好的开始。
将 2143072043
转换为十六进制,我们得到 7FBCAF2B
这是散列的最后 4 个字节。
因此你想获得散列和截断的结果,我将 BITAND 实现,但上次我使用雪花 BIT 函数时,它们确实允许十六进制输入,所以不用键入 a相当清楚 0xFFffFFff
我们将使用那个 4294967295
的小数,因此这应该适合你:
select bitand(sha1('214163915155286000'), 4294967295);
非常感谢 Gokhan 的洞察力,登录雪花,并阅读 BITSHIFTLEFT/RIGHT 的手册。我们可以使用移位,但输出是 128 位数字,而不是 64 位,正如我假设的那样,为了正确扩展符号位,我们必须移位 96 位,这段代码显示有效:
SELECT
column1 as input,
sha1(input) as sha1,
right(sha1,8) as right8,
to_number(right8,'XXXXXXXX') as int32,
BITSHIFTRIGHT(BITSHIFTLEFT(int32,96),96) as result
FROM VALUES
('214163915155286001'),
('214163915155286000')
ORDER BY 1;
给出输出:
INPUT
SHA1
RIGHT8
INT32
RESULT
214163915155286000
374543ac5a9890af8cd863eb7c98e7467fbcaf2b
7fbcaf2b
2143072043
2143072043
214163915155286001
1911d3df794846fbc74e0e4cf29133459466e0e7
9466e0e7
2489770215
-1805197081
所以 SQL 的更紧凑和最后的块可以是:
BITSHIFTRIGHT(BITSHIFTLEFT(to_number(right(sha1(input),8),'XXXXXXXX'),96),96)
昨天我检查你的 post 时,我注意到 Ms SQL 服务器使用 SHA1 哈希的最后 8 位数字(正如 Simon 指出的那样),所以我写了这个查询:
select to_number(right( sha1('214163915155286000'), 8 ), 'XXXXXXXX' );
它按预期生成了 2143072043,但不幸的是,如果我们想模拟 SQL 女士服务器的行为,这还不够。
如果转换'214163915155286001',上面的转换returns2489770215。如果我们在MsSQLServer中进行精确转换,则returns-1805197081。问题是,SQL 服务器女士将结果存储在“有符号整数”中。在 Snowflake 中,没有带符号的整数。整数与 NUMBER 同义。所以我们需要处理“signed”位。这就是我编写以下 UDF 的原因:
create or replace function convertMStoSF( SHA varchar )
returns NUMBER
language SQL
as
$$
IFF( bitand( to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) , 2147483648 ) > 0,
- 2147483648 + bitand( 2147483647, to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) ) ,
to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) )
$$;
它获取最后 8 位数字,转换为数字,并检查有符号位。如果为 1,则计算有符号值。如果为 0,则直接 returns 数字。在UDF中,我使用了十进制表示而不是十六进制:
0x7FFFFFFF -> 2147483647
0x80000000 -> 2147483648
这里是一个测试结果的查询:
select '214163915155286000' A, convertMStoSF( A ), '214163915155286001' B, convertMStoSF( B );
+--------------------+--------------------+--------------------+--------------------+
| A | CONVERTMSTOSF( A ) | B | CONVERTMSTOSF( B ) |
+--------------------+--------------------+--------------------+--------------------+
| 214163915155286000 | 2143072043 | 214163915155286001 | -1805197081 |
+--------------------+--------------------+--------------------+--------------------+
我不得不说我不确定它是否 100% 正确,因为我只用几个样本数字进行测试。
我需要一个 SQL 来自 Snowflake 的服务器等效 Hashbytes SHA1 输出
SQL 服务器:
select hashbytes('sha1',cast('214163915155286000' as varchar(18)))*1
或
select cast(hashbytes('sha1',cast('214163915155286000' as varchar(18))) as int)
SQL 服务器输出:
2143072043
我可以使用下面的方法从 snowflake 生成 hashbytes 输出,但现在我无法将它转换成数值
select to_char(to_binary(sha1('214163915155286000'), 'hex'), 'base64') as Result;
部分雪花输出:
N0VDrFqYkK+M2GPrfJjnRn+8rys=
Snowflake 的预期输出:
2143072043
仅供参考 - 我在此处尝试了 SQL 服务器代码
所以在 SQL 服务器中进行少量播放。
select '214163915155286000' as s,
hashbytes('sha1', '214163915155286000') as h,
cast(hashbytes('sha1', '214163915155286000') as int) as i
;
给出:
s, 214163915155286000
h, 0x374543AC5A9890AF8CD863EB7C98E7467FBCAF2B
i, 2143072043
所以我的 SQL 和你的一样,作为一个好的开始。
将 2143072043
转换为十六进制,我们得到 7FBCAF2B
这是散列的最后 4 个字节。
因此你想获得散列和截断的结果,我将 BITAND 实现,但上次我使用雪花 BIT 函数时,它们确实允许十六进制输入,所以不用键入 a相当清楚 0xFFffFFff
我们将使用那个 4294967295
的小数,因此这应该适合你:
select bitand(sha1('214163915155286000'), 4294967295);
非常感谢 Gokhan 的洞察力,登录雪花,并阅读 BITSHIFTLEFT/RIGHT 的手册。我们可以使用移位,但输出是 128 位数字,而不是 64 位,正如我假设的那样,为了正确扩展符号位,我们必须移位 96 位,这段代码显示有效:
SELECT
column1 as input,
sha1(input) as sha1,
right(sha1,8) as right8,
to_number(right8,'XXXXXXXX') as int32,
BITSHIFTRIGHT(BITSHIFTLEFT(int32,96),96) as result
FROM VALUES
('214163915155286001'),
('214163915155286000')
ORDER BY 1;
给出输出:
INPUT | SHA1 | RIGHT8 | INT32 | RESULT |
---|---|---|---|---|
214163915155286000 | 374543ac5a9890af8cd863eb7c98e7467fbcaf2b | 7fbcaf2b | 2143072043 | 2143072043 |
214163915155286001 | 1911d3df794846fbc74e0e4cf29133459466e0e7 | 9466e0e7 | 2489770215 | -1805197081 |
所以 SQL 的更紧凑和最后的块可以是:
BITSHIFTRIGHT(BITSHIFTLEFT(to_number(right(sha1(input),8),'XXXXXXXX'),96),96)
昨天我检查你的 post 时,我注意到 Ms SQL 服务器使用 SHA1 哈希的最后 8 位数字(正如 Simon 指出的那样),所以我写了这个查询:
select to_number(right( sha1('214163915155286000'), 8 ), 'XXXXXXXX' );
它按预期生成了 2143072043,但不幸的是,如果我们想模拟 SQL 女士服务器的行为,这还不够。
如果转换'214163915155286001',上面的转换returns2489770215。如果我们在MsSQLServer中进行精确转换,则returns-1805197081。问题是,SQL 服务器女士将结果存储在“有符号整数”中。在 Snowflake 中,没有带符号的整数。整数与 NUMBER 同义。所以我们需要处理“signed”位。这就是我编写以下 UDF 的原因:
create or replace function convertMStoSF( SHA varchar )
returns NUMBER
language SQL
as
$$
IFF( bitand( to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) , 2147483648 ) > 0,
- 2147483648 + bitand( 2147483647, to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) ) ,
to_number(right( sha1( SHA ), 8 ), 'XXXXXXXX' ) )
$$;
它获取最后 8 位数字,转换为数字,并检查有符号位。如果为 1,则计算有符号值。如果为 0,则直接 returns 数字。在UDF中,我使用了十进制表示而不是十六进制:
0x7FFFFFFF -> 2147483647
0x80000000 -> 2147483648
这里是一个测试结果的查询:
select '214163915155286000' A, convertMStoSF( A ), '214163915155286001' B, convertMStoSF( B );
+--------------------+--------------------+--------------------+--------------------+
| A | CONVERTMSTOSF( A ) | B | CONVERTMSTOSF( B ) |
+--------------------+--------------------+--------------------+--------------------+
| 214163915155286000 | 2143072043 | 214163915155286001 | -1805197081 |
+--------------------+--------------------+--------------------+--------------------+
我不得不说我不确定它是否 100% 正确,因为我只用几个样本数字进行测试。