Bigquery中的模运算。计算`x%y`,其中`x`是128位数字

问题描述 投票:1回答:1

[将字符串的MD5用作整数x的128位表示,如何在Google Bigquery中计算x % y,其中y通常相对较小(大约1000)?

Bigquery具有MD5函数,返回具有16个字节(即128位)的BYTES类型的结果。

(背景:这是为了计算确定性伪随机数。但是,出于传统和兼容性原因,我在算法上没有灵活性!即使我们知道它具有(very slight) bias。]

对于不同的输入字符串和不同的模量,每天需要完成数百万/十亿次,因此希望可以有效地完成。作为回退,我可以使用另一种语言在外部进行计算,然后再上传到Bigquery;但是如果我可以直接在Bigquery中这样做,那就太好了。

我研究了很多数论,所以也许我们可以使用一些数学技巧。但是,我仍然停留在更基本的BiqQuery问题上

  • 如何将字节数组转换为某种“大整数”类型?
  • 我可以从BYTES数组访问字节的子范围吗?
  • 给出一个字节(或者可能是四个字节?),我可以将其转换为可以对其进行算术运算的整数类型吗?
sql google-bigquery modulo largenumber
1个回答
0
投票

具有power of math和冗长的SQL函数:

CREATE TEMP FUNCTION md5_numbers_array(str ANY TYPE) AS ((
  SELECT ARRAY_AGG(CAST(CONCAT("0x", TO_HEX(b)) AS INT64))
  FROM UNNEST((
    SELECT SPLIT(MD5(str), CAST('' AS BYTES))
  )) b
));
CREATE TEMP FUNCTION modulo_md5 (str ANY TYPE, m ANY TYPE) AS ((
  SELECT MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(0 
    * 256 + num[OFFSET(0)], m) 
    * 256 + num[OFFSET(1)], m )  
    * 256 + num[OFFSET(2)], m ) 
    * 256 + num[OFFSET(3)], m ) 
    * 256 + num[OFFSET(4)], m )  
    * 256 + num[OFFSET(5)], m ) 
    * 256 + num[OFFSET(6)], m ) 
    * 256 + num[OFFSET(7)], m )  
    * 256 + num[OFFSET(8)], m ) 
    * 256 + num[OFFSET(9)], m ) 
    * 256 + num[OFFSET(10)], m )  
    * 256 + num[OFFSET(11)], m ) 
    * 256 + num[OFFSET(12)], m ) 
    * 256 + num[OFFSET(13)], m )  
    * 256 + num[OFFSET(14)], m ) 
    * 256 + num[OFFSET(15)], m ) 
  FROM (SELECT md5_numbers_array(str) num)
));

SELECT title, modulo_md5(title, 177) result, TO_HEX(MD5(title)) md5
FROM `fh-bigquery.wikipedia_v3.pageviews_2019` 
WHERE wiki='en'
LIMIT 100000

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.