Подтвердить что ты не робот

Создание произвольной строки UTF-8 в Python

Я хочу проверить обработку Юникодом моего кода. Есть ли что-нибудь, что я могу поставить в random.choice() для выбора из всего диапазона Unicode, желательно не внешнего модуля? Ни Google, ни StackOverflow не имеют ответа.

Изменить: похоже, что это сложнее, чем ожидалось, поэтому я перефразирую вопрос. Является ли следующий код достаточным для создания всех допустимых неконтролируемых символов в Юникоде?

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

Ответ 2

Люди могут найти свой путь здесь, основываясь главным образом на названии вопроса, поэтому здесь можно создать случайную строку, содержащую множество символов Юникода. Чтобы включить больше (или меньше) возможных символов, просто расширьте эту часть примера с помощью диапазонов кодовых точек, которые вы хотите.

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))

Ответ 3

Вот примерная функция, которая, вероятно, создает случайную хорошо сформированную последовательность UTF-8, как определено в таблице 3-7 Unicode 5.0.0:

#!/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 я не могу проверить это полностью. Также обратите внимание, что символы неравномерно распределены (но каждый байт в последовательности).

Ответ 4

Это зависит от того, насколько тщательно вы хотите провести тестирование и как точно вы хотите генерировать. Вполне, Unicode - это 21-битный код (U + 0000.. U + 10FFFF). Тем не менее, некоторые довольно большие куски этого диапазона отложены для пользовательских персонажей. Вы хотите беспокоиться о создании комбинирования символов в начале строки (потому что они должны появляться только после другого символа)?

Базовый подход, который я бы принял, случайным образом генерирует код кода Unicode (например, U + 2397 или U + 31232), проверяет его в контексте (является ли он законным символом, может ли он отображаться здесь в строке) и кодировать действительный кода в UTF-8.

Если вы просто хотите проверить, правильно ли ваш код правильно обрабатывает UTF-8, вы можете использовать гораздо более простые схемы генерации.

Обратите внимание, что вам нужно знать, чего ожидать от ввода - иначе вы не будете тестировать; вы экспериментируете.

Ответ 5

Выполняет код, который печатает любой печатный символ UTF-8:

print(''.join(tuple(chr(l) for l in range(1, 0x10ffff)
                    if chr(l).isprintable())))

Все символы присутствуют, даже те, которые не обрабатываются используемым шрифтом. and not chr(l).isspace() может быть добавлен, чтобы отфильтровать все пробельные символы. (включая вкладку)

Ответ 6

Так как Unicode - это всего лишь ряд кодов хорошо, как насчет использования unichr() для получения строки Unicode, соответствующей случайному числу от 0 до 0xFFFF?
(Конечно, это даст только один код, поэтому итерации по мере необходимости)

Ответ 7

Вы можете загрузить сайт, написанный на греческом или немецком языке, который использует unicode и передает его вашему коду.

Ответ 8

Отвечая на пересмотренный вопрос:

Да, при строгом определении "управляющих символов" - обратите внимание, что вы не будете включать CR, LF и TAB; это то, что вы хотите?

Пожалуйста, подумайте о том, чтобы ответить на мое более раннее приглашение, чтобы сообщить нам, что вы действительно пытаетесь сделать.