在Python中生成随机UTF-8字符串

l0b*_*0b0 23 python random unicode utf-8

我想测试我的代码的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')
    )
Run Code Online (Sandbox Code Playgroud)

Jac*_*Wan 15

人们可能主要基于问题标题找到他们的方式,因此这里有一种生成包含各种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))
Run Code Online (Sandbox Code Playgroud)

  • @morfys没有,但是我只是对其进行了编辑。感谢您的询问。 (2认同)

Gum*_*mbo 10

您可以使用Markus Kuhn进行的UTF-8压力测试.

另见真正好,坏的UTF-8示例测试数据.

  • 很好的答案,但实际上没有回答问题. (3认同)

Phi*_*ipp 7

下面是一个示例函数,可能会创建一个随机格式良好的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)))
Run Code Online (Sandbox Code Playgroud)

由于Unicode标准的广泛性,我无法彻底测试.另请注意,字符的分布不均匀(但序列中的每个字节都是).


alu*_*iak 6

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

print(''.join(tuple(chr(i) for i in range(32, 0x110000) if chr(i).isprintable())))
Run Code Online (Sandbox Code Playgroud)

所有可打印的字符都包含在上面,即使是当前字体未打印的字符。and not chr(i).isspace()可以添加该子句以过滤掉空白字符。