Google bigquery 如何从&;从CIDR BigQuery到Ip地址

Google bigquery 如何从&;从CIDR BigQuery到Ip地址,google-bigquery,geoip,Google Bigquery,Geoip,BigQuery提供更新的geoip2公共数据集[BigQuery publicdata->geolite2->ipv4\u city\u blocks],其中包含具有ipv4 CIDR值的网络列 如何通过BigQuery SQL(而不是通过BigQuery外部的实用程序)将网络列中的CIDR值转换为起始和结束ip地址值,以便查找ip地址是否在范围内?如果您可以提供查询以获取表中CIDR值的范围ips,这将非常有用。您需要检查的第一件事是,如果该函数已经存在,请参阅 如果没有,则需要使用(UDF

BigQuery提供更新的geoip2公共数据集[BigQuery publicdata->geolite2->ipv4\u city\u blocks],其中包含具有ipv4 CIDR值的网络列


如何通过BigQuery SQL(而不是通过BigQuery外部的实用程序)将网络列中的CIDR值转换为起始和结束ip地址值,以便查找ip地址是否在范围内?如果您可以提供查询以获取表中CIDR值的范围ips,这将非常有用。

您需要检查的第一件事是,如果该函数已经存在,请参阅

如果没有,则需要使用(UDF),它允许您使用另一个SQL表达式或另一种编程语言(如JavaScript)创建函数

请记住,在使用UDF JavaScript函数时,BigQuery使用函数在每个执行碎片上的内容初始化JavaScript环境。没有任何优化可以避免加载环境,因此会减慢查询速度


关于站点,有一个实用程序可以将“网络”列转换为起始/结束IP或起始/结束整数。有关详细信息,请参阅网站。

此查询将完成以下工作:

# replace with your source of IP addresses
# here I'm using the same Wikipedia set from the previous article
WITH source_of_ip_addresses AS (
  SELECT REGEXP_REPLACE(contributor_ip, 'xxx', '0')  ip, COUNT(*) c
  FROM `publicdata.samples.wikipedia`
  WHERE contributor_ip IS NOT null  
  GROUP BY 1
)
SELECT city_name, SUM(c) c, ST_GeogPoint(AVG(longitude), AVG(latitude)) point
FROM (
  SELECT ip, city_name, c, latitude, longitude, geoname_id
  FROM (
    SELECT *, NET.SAFE_IP_FROM_STRING(ip) & NET.IP_NET_MASK(4, mask) network_bin
    FROM source_of_ip_addresses, UNNEST(GENERATE_ARRAY(9,32)) mask
    WHERE BYTE_LENGTH(NET.SAFE_IP_FROM_STRING(ip)) = 4
  )
  JOIN `fh-bigquery.geocode.201806_geolite2_city_ipv4_locs`  
  USING (network_bin, mask)
)
WHERE city_name  IS NOT null
GROUP BY city_name, geoname_id
ORDER BY c DESC
LIMIT 5000`
有关以下内容的详细信息:


    • 下面是BigQuery标准SQL

      #standardSQL
      CREATE TEMP FUNCTION cidrToRange(CIDR STRING)
      RETURNS STRUCT<start_IP STRING, end_IP STRING>
      LANGUAGE js AS """
        var beg = CIDR.substr(CIDR,CIDR.indexOf('/'));
        var end = beg;
        var off = (1<<(32-parseInt(CIDR.substr(CIDR.indexOf('/')+1))))-1; 
        var sub = beg.split('.').map(function(a){return parseInt(a)});
        var buf = new ArrayBuffer(4); 
        var i32 = new Uint32Array(buf);
        i32[0]  = (sub[0]<<24) + (sub[1]<<16) + (sub[2]<<8) + (sub[3]) + off;
        var end = Array.apply([],new Uint8Array(buf)).reverse().join('.');
        return {start_IP: beg, end_IP: end};
      """; 
      SELECT network, IP_range.*
      FROM `bigquery-public-data.geolite2.ipv4_city_blocks`,
      UNNEST([cidrToRange(network)]) IP_range   
      
      #标准SQL
      创建临时函数cidrToRange(CIDR字符串)
      返回结构
      语言js为“”
      var beg=CIDR.substr(CIDR,CIDR.indexOf('/');
      var-end=beg;
      var off=(1)