【问题标题】:Testing bitmask when stored as integer and available as string以整数形式存储并以字符串形式提供时测试位掩码
【发布时间】:2023-01-30 04:06:20
【问题描述】:

我有一个适用于字段的整数值(1、2、4、8、16 等)的位掩码(实际上是“标志掩码”),我需要将其存储在(文本)日志文件中。我有效存储的内容类似于“x=296”,它表示对于字段“x”,设置了标志 256、32 和 8。

在搜索日志时,如何轻松搜索到这个文本字符串(“x=nnn”),并从“nnn”的值判断是否设置了特定标志?例如,我如何查看数字并知道设置了标志 8?

我知道如果我们正在进行“真正的”位掩码处理,这是一个有点微不足道的问题,但我以前从未见过这样问过 - 日志搜索只会进行字符串匹配,所以它只会看到值“296 " 并且没有办法将其转换为其构成标志 - 我们只是使用基本的字符串搜索,其中可能包含一些简单的 SQL。

【问题讨论】:

    标签: bitmask bitflags


    【解决方案1】:

    确定是否在值“nnn”中设置了特定标志的一种方法是使用按位运算符来检查该标志是否存在于值中。例如。要检查标志 8 是否设置在值 296 中,您可以使用按位运算符检查值 8 是否存在:

    if (nnn & 8) == 8:
    print("flag 8 is set")
    

    我能想到的另一种方法是使用正则表达式检查标志 8 的值是否存在于日志字符串“x=nnn”中,您可以在其中搜索日志中的字符串“8”。

    import re
    log_string = "x=296"
    if re.search("8", log_string):
       print("flag 8 is set")
    

    您还可以使用一个函数,该函数将日志字符串和标志作为输入并返回一个布尔值,指示是否在日志字符串中设置了标志。

    def check_flag(log_string, flag):
        nnn = int(log_string.split('=')[1])
        return (nnn & flag) == flag
    
    if check_flag("x=296", 8):
        print("flag 8 is set")
    

    【讨论】:

    • 如前所述,我们在这里只能使用 SQL 和字符串操作,因此标志操作的(明显的)用法是行不通的。我不是进行解析的人,但我确信用于解析日志文件的任何语言或脚本都非常陈旧并且几乎无法更改 - 没有 python,没有 Go,没有 Javascript,没有......任何。
    【解决方案2】:

    最好的办法是进行完整的字符串正则表达式匹配。

    对于第 8 位设置,请执行以下操作:

    SELECT log_line
    FROM log_table
    WHERE log_line
    RLIKE 'x=(128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255)[^0-9]'
    

    或者简化为:

    RLIKE 'x=(12[89]|1[3-9][0-9]|2[0-4][0-9]|25[0-5])[^0-9]'
    

    字符串 x= 必须存在于日志中,后跟十进制数字和非十进制数字。

    对于位 2 设置,请执行以下操作:

    SELECT log_line FROM log_table WHERE log_line RLIKE 'x=(2|3|6|7|10|11|14|15|18|19|22|23|26|27|30|31|34|35|38|39|42|43|46|47|50|51|54|55|58|59|62|63|66|67|70|71|74|75|78|79|82|83|86|87|90|91|94|95|98|99|102|103|106|107|110|111|114|115|118|119|122|123|126|127|130|131|134|135|138|139|142|143|146|147|150|151|154|155|158|159|162|163|166|167|170|171|174|175|178|179|182|183|186|187|190|191|194|195|198|199|202|203|206|207|210|211|214|215|218|219|222|223|226|227|230|231|234|235|238|239|242|243|246|247|250|251|254|255)[^0-9]'
    

    我在一些实时数据上测试了 bit2:

    SELECT count(log_line)
    ...
    
    count(log_line)
    128

    一组中的 1 行(0.002 秒)

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 1970-01-01
      • 2016-04-06
      • 2017-04-21
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多