本文分享自天翼雲開發者社區《從random隨機數看驗證碼重複數字》.作者:王****淋

## 推導:

1. 有6個不同數字

- (0個重複數字: 1+1+1+1+1+1):

$$p(6) = C_{10}^6 * 6! \div 10^6$$

2. 有5個不同數字

- (某個數字重複了2次: 1+1+1+1+2):

$$p(5) = (\frac{C_{10}^5 * C_5^1}{2!*1!*1!*1!*1!} ) * 6! \div 10^6$$

$$     = (\frac{C_{10}^5 * C_5^1}{2!} ) * 6! \div 10^6$$

3. 有4個不同數字

- (某個數字重複了3次: 1+1+1+3,或某2個數字各重複2次: 1+1+2+2)。(省略$1!$):

$$p(4) = (\frac{C_{10}^4 * C_4^1}{3!} + \frac{C_{10}^4 * C_4^2}{2!*2!}) * 6! \div 10^6$$

4. 有3個不同數字

- (某個數字重複了4次: 1+1+4,或某個數字重複3次+某數字重複2次: 1+3+2, 或3個數字哥重複2次: 2+2+2):

$$p(3) = (\frac{C_{10}^3 * C_3^1}{4!} + \frac{C_{10}^3 * C_3^1 * C_2^1}{3!*2!}  +\frac{C_{10}^3 * C_3^3}{2!*2!*2!}) * 6! \div 10^6$$

5. 有2個不同數字

- (某個數字重複了5次: 1+5,或某個數字重複4次+某數字重複2次: 4+2, 或2個數字哥重複3次: 3+3): (省略$1!$):

$$p(2) = (\frac{C_{10}^2 * C_2^1}{5!} + \frac{C_{10}^2 * C_2^1}{4!*2!} + \frac{C_{10}^2 * C_2^2}{3!*3!}) * 6! \div 10^6$$

6. 有1個不同數字(6個相同的重複數字):

$$p(1) = \frac{C_{10}^1}{6!} * 6! \div 10^6$$

 

## 蒙特卡洛

```py 

import random


# 6位驗證碼, 相同數字的概率: 蒙特卡洛

def mtkr(count:int=10, is_show:bool=True, debug:bool = False):    

    ans = [0 for i in range(6)]

    for i in range(count):

        array_i = [random.randint(0, 9) for i in range(6)]              

        n = len(list(set(array_i)))

        if debug:

            print(n, ": ", array_i)

        ans[6-n] += 1

    # end_for

   

    if is_show:

        print('-' * 30)

        print('蒙特卡洛: count:', count, ";  \n模擬結果: ")

        for i in range(6):

            print("unique", 6-i, ": ", ans[i]/count)

    return [i/count for i in ans]


ans = mtkr(100000, is_show=True, debug=False)

print(ans)

res_plot(ans)

 

# 結果:

模擬結果:

# unique 6 : 0.15148

# unique 5 : 0.45396

# unique 4 : 0.32748

# unique 3 : 0.0643

# unique 2 : 0.00278 u

# nique 1 : 0.0

```