【问题标题】:How to get From & To Ip Address from CIDR BigQuery如何从 CIDR BigQuery 获取 From & To IP 地址
【发布时间】:2019-12-03 11:41:03
【问题描述】:

BigQuery 提供更新的 geoip2 公共数据集 here [bigquery-publicdata -> geolite2 -> ipv4_city_blocks],其中包含具有 IPv4 CIDR 值的网络列。

如何通过 BigQuery SQL(而不是通过 BigQuery 外部的实用程序)将网络列中的 CIDR 值转换为开始和结束 IP 地址值,以便我可以找到 IP 地址是否在某个范围内?如果您可以提供查询以获取表中 CIDR 值的范围 ips,将会很有帮助。

【问题讨论】:

    标签: google-bigquery geoip


    【解决方案1】:

    以下是 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   
    

    处理所有 3,037,858 行大约需要 60 秒,结果如下所示

    【讨论】:

      【解决方案2】:

      这个查询将完成这项工作:

      # 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`
      

      了解更多详情:

      【讨论】:

        【解决方案3】:

        首先需要检查的是,如果该功能已经存在,请参考BigQuery Functions and Operators documentation

        如果没有,您需要使用Standard SQL User-Defined Functions (UDF),它允许您使用其他 SQL 表达式或其他编程语言(例如 JavaScript)创建函数。

        请注意,在使用 UDF JavaScript 函数时,BigQuery 会在每个执行分片上使用函数的内容来初始化 JavaScript 环境。没有优化来避免加载环境,因此会减慢查询速度。

        关于GeoIP2 City and Country CSV Databases 站点,有一个实用程序可以将“网络”列转换为开始/结束 IP 或开始/结束整数。详情请参考Github网站。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-23
          • 1970-01-01
          相关资源
          最近更新 更多