簡體   English   中英

在Python中生成隨機UTF-8字符串

[英]Generate random UTF-8 string in Python

我想測試我的代碼的Unicode處理。 我可以在random.choice()中選擇從整個Unicode范圍中選擇,最好不是外部模塊嗎? 谷歌和StackOverflow似乎都沒有答案。

編輯:看起來這比預期的更復雜,所以我將重新解釋這個問題 - 以下代碼是否足以在Unicode中生成所有有效的非控制字符

unicode_glyphs = ''.join(
    unichr(char)
    for char in xrange(1114112) # 0x10ffff + 1
    if unicodedata.category(unichr(char))[0] in ('LMNPSZ')
    )

人們可能主要基於問題標題找到他們的方式,因此這里有一種生成包含各種Unicode字符的隨機字符串的方法。 要包含更多(或更少)可能的字符,只需使用所需的代碼點范圍擴展該部分示例。

import random

def get_random_unicode(length):

    try:
        get_char = unichr
    except NameError:
        get_char = chr

    # Update this to include code point ranges to be sampled
    include_ranges = [
        ( 0x0021, 0x0021 ),
        ( 0x0023, 0x0026 ),
        ( 0x0028, 0x007E ),
        ( 0x00A1, 0x00AC ),
        ( 0x00AE, 0x00FF ),
        ( 0x0100, 0x017F ),
        ( 0x0180, 0x024F ),
        ( 0x2C60, 0x2C7F ),
        ( 0x16A0, 0x16F0 ),
        ( 0x0370, 0x0377 ),
        ( 0x037A, 0x037E ),
        ( 0x0384, 0x038A ),
        ( 0x038C, 0x038C ),
    ]

    alphabet = [
        get_char(code_point) for current_range in include_ranges
            for code_point in range(current_range[0], current_range[1] + 1)
    ]
    return ''.join(random.choice(alphabet) for i in range(length))

if __name__ == '__main__':
    print('A random string: ' + get_random_unicode(10))

下面是一個示例函數,可能會創建一個隨機格式良好的UTF-8序列,如Unicode 5.0.0的表3-7中所定義:

#!/usr/bin/env python3.1

# From Table 3–7 of the Unicode Standard 5.0.0

import random

def byte_range(first, last):
    return list(range(first, last+1))

first_values = byte_range(0x00, 0x7F) + byte_range(0xC2, 0xF4)
trailing_values = byte_range(0x80, 0xBF)

def random_utf8_seq():
    first = random.choice(first_values)
    if first <= 0x7F:
        return bytes([first])
    elif first <= 0xDF:
        return bytes([first, random.choice(trailing_values)])
    elif first == 0xE0:
        return bytes([first, random.choice(byte_range(0xA0, 0xBF)), random.choice(trailing_values)])
    elif first == 0xED:
        return bytes([first, random.choice(byte_range(0x80, 0x9F)), random.choice(trailing_values)])
    elif first <= 0xEF:
        return bytes([first, random.choice(trailing_values), random.choice(trailing_values)])
    elif first == 0xF0:
        return bytes([first, random.choice(byte_range(0x90, 0xBF)), random.choice(trailing_values), random.choice(trailing_values)])
    elif first <= 0xF3:
        return bytes([first, random.choice(trailing_values), random.choice(trailing_values), random.choice(trailing_values)])
    elif first == 0xF4:
        return bytes([first, random.choice(byte_range(0x80, 0x8F)), random.choice(trailing_values), random.choice(trailing_values)])

print("".join(str(random_utf8_seq(), "utf8") for i in range(10)))

由於Unicode標准的廣泛性,我無法徹底測試。 另請注意,字符的分布不均勻(但序列中的每個字節都是)。

遵循打印任何可打印UTF-8字符的代碼:

print(''.join(tuple(chr(i) for i in range(32, 0x110000) if chr(i).isprintable())))

所有可打印字符都包含在上面,甚至包括那些當前字體不打印的字符。 可以添加子句and not chr(i).isspace()來過濾掉空格字符。

這取決於您希望進行測試的程度以及您希望如何准確地進行測試。 完整地,Unicode是一個21位代碼集(U + 0000 .. U + 10FFFF)。 但是,該范圍的一些相當大的塊被留出用於自定義字符。 您是否想要擔心在字符串的開頭生成組合字符(因為它們應該僅出現在另一個字符之后)?

我采用的基本方法是隨機生成一個Unicode代碼點(比如U + 2397或U + 31232),在上下文中驗證它(它是一個合法的字符;它是否可以出現在字符串中)並編碼有效的代碼點UTF-8。

如果您只想檢查您的代碼是否正確處理格式錯誤的UTF-8,您可以使用更簡單的生成方案。

請注意,您需要知道在輸入時會發生什么 - 否則您不會測試; 你正在試驗。

由於Unicode只是一系列 - 井代碼,使用unichr()獲取對應於0到0xFFFF之間的隨機數的unicode字符串怎么樣?
(當然那只會給出一個代碼點,所以根據需要進行迭代)

您可以下載使用unicode編寫的希臘語或德語網站,並將其提供給您的代碼。

回答修改后的問題:

是的,根據對“控制字符”的嚴格定義 - 請注意,您不會包含CR,LF和TAB; 那是你要的嗎?

請考慮回復我之前的邀請,告訴我們您的確想要做什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM