产品展示

扑克检测算法

2025-12-24 13:39:40

扑克检测是一种常用的随机性测试方法,用于评估二进制序列的随机性。该测试通过分析序列中固定长度模式的出现频率来判断序列是否具有随机特性。

算法原理

基本思想

扑克检测将输入序列划分为多个长度为m的子序列(称为"手牌"),然后统计每种可能模式出现的频率。在一个真正的随机序列中,所有可能的m位模式应该以大致相等的概率出现。

数学基础

  • 设序列长度为n
  • 选择手牌长度m(通常m满足 ⌊n/m⌋ ≥ 5·2^m)
  • 可能的手牌类型数量:k = 2^m
  • 期望每种手牌出现的次数:n/m ÷ k
  • 算法实现

    python

    import math

    from collections import Counter

    from scipy.stats import chi2

    def poker_test(bit_sequence, m):

    执行扑克检测

    参数:

    bit_sequence -

  • 二进制序列(字符串或列表)
  • m -

  • 手牌长度
  • 返回:

    dict -

  • 包含测试结果的字典
  • # 确保输入是字符串格式

    if isinstance(bit_sequence, list):

    sequence = ''.join(str(bit) for bit in bit_sequence)

    else:

    sequence = str(bit_sequence)

    n = len(sequence)

    # 检查参数有效性

    if n

    raise ValueError("序列长度不足以进行有效的扑克检测")

    # 划分手牌

    hands = []

    for i in range(0, n

  • m + 1, m):
  • hand = sequence[i:i+m]

    if len(hand) == m: # 只取完整的手牌

    hands.append(hand)

    # 统计每种手牌出现的次数

    hand_counts = Counter(hands)

    # 计算卡方统计量

    k = 2 ** m # 可能的手牌类型数

    expected_count = len(hands) / k

    chi_square = 0

    for count in hand_counts.values:

    chi_square += (count

  • expected_count) ** 2 / expected_count
  • # 计算p值

    degrees_of_freedom = k

  • 1
  • p_value = 1

  • chi2.cdf(chi_square, degrees_of_freedom)
  • return {

    'hand_length': m,

    'total_hands': len(hands),

    'unique_hands': len(hand_counts),

    'expected_count': expected_count,

    'chi_square': chi_square,

    'degrees_of_freedom': degrees_of_freedom,

    'p_value': p_value,

    'is_random': p_value > 0.01 # 常用的显著性水平

    def advanced_poker_test(bit_sequence, m_values=None):

    高级扑克检测,对多个m值进行测试

    参数:

    bit_sequence -

  • 二进制序列
  • m_values -

  • 要测试的手牌长度列表
  • 返回:

    dict -

  • 包含所有测试结果的字典
  • if m_values is None:

    # 根据序列长度自动选择合适的m值

    n = len(bit_sequence)

    m_values = []

    for m in [3, 4, 5]:

    if math.floor(n / m) >= 5 * (2 ** m):

    扑克检测算法

    m_values.append(m)

    results = {}

    for m in m_values:

    try:

    results[f'm={m}'] = poker_test(bit_sequence, m)

    except ValueError as e:

    results[f'm={m}'] = {'error': str(e)}

    return results

    # 示例用法

    if __name__ == "__main__":

    # 生成随机序列进行测试

    import random

    # 生成10000位的随机序列

    random_bits = ''.join(str(random.randint(0, 1)) for _ in range(10000))

    # 执行扑克检测

    result = poker_test(random_bits, 4)

    print("扑克检测结果:")

    print(f"手牌长度: {result['hand_length']}")

    print(f"总手牌数: {result['total_hands']}")

    print(f"不同手牌类型数: {result['unique_hands']}")

    print(f"期望每种手牌出现次数: {result['expected_count']:.2f}")

    print(f"卡方统计量: {result['chi_square']:.4f}")

    print(f"自由度: {result['degrees_of_freedom']}")

    print(f"P值: {result['p_value']:.6f}")

    print(f"是否随机: {'是' if result['is_random'] else '否'}")

    # 多参数测试

    WPKAPP下载

    print("\

    多参数扑克检测:")

    multi_results = advanced_poker_test(random_bits)

    for key, res in multi_results.items:

    if 'error' not in res:

    print(f"{key}: P值 = {res['p_value']:.6f}, 随机性: {'通过' if res['is_random'] else '未通过'}")

    算法特点

    优点

    1. 敏感性高:能够检测序列中的周期性模式和规律性

    2. 灵活性好:可以通过调整m值适应不同长度的序列

    3. 理论基础强:基于严格的统计学原理

    局限性

    1. 对序列长度敏感:需要足够长的序列才能获得可靠结果

    2. 参数选择重要:m值的选择会影响测试效果

    3. 计算复杂度:随着m增大,计算量指数增长

    应用场景

    1. 密码学:评估伪随机数生成器的质量

    2. 通信系统:测试通信信道的随机特性

    3. 统计质量控制:检测生产过程中的随机性

    4. 科学研究:分析实验数据的随机分布特性

    注意事项

    1. 序列长度:建议序列长度至少为1000位

    2. m值选择:通常选择3≤m≤5,确保每种手牌期望出现次数≥5

    3. 显著性水平:常用α=0.01作为判断标准

    4. 多重测试:当进行多个m值测试时,应考虑多重比较问题

    这个算法提供了一种有效的方法来评估二进制序列的随机性,是随机性测试套件中的重要组成部分。