Ответ 1
Существует стресс-тест UTF-8 от Markus Kuhn, который вы могли бы использовать.
См. также Действительно хорошие, плохие примеры тестовых данных UTF-8.
Я хочу проверить обработку Юникодом моего кода. Есть ли что-нибудь, что я могу поставить в 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')
)
Существует стресс-тест UTF-8 от Markus Kuhn, который вы могли бы использовать.
См. также Действительно хорошие, плохие примеры тестовых данных UTF-8.
Люди могут найти свой путь здесь, основываясь главным образом на названии вопроса, поэтому здесь можно создать случайную строку, содержащую множество символов Юникода. Чтобы включить больше (или меньше) возможных символов, просто расширьте эту часть примера с помощью диапазонов кодовых точек, которые вы хотите.
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, как определено в таблице 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 я не могу проверить это полностью. Также обратите внимание, что символы неравномерно распределены (но каждый байт в последовательности).
Это зависит от того, насколько тщательно вы хотите провести тестирование и как точно вы хотите генерировать. Вполне, Unicode - это 21-битный код (U + 0000.. U + 10FFFF). Тем не менее, некоторые довольно большие куски этого диапазона отложены для пользовательских персонажей. Вы хотите беспокоиться о создании комбинирования символов в начале строки (потому что они должны появляться только после другого символа)?
Базовый подход, который я бы принял, случайным образом генерирует код кода Unicode (например, U + 2397 или U + 31232), проверяет его в контексте (является ли он законным символом, может ли он отображаться здесь в строке) и кодировать действительный кода в UTF-8.
Если вы просто хотите проверить, правильно ли ваш код правильно обрабатывает UTF-8, вы можете использовать гораздо более простые схемы генерации.
Обратите внимание, что вам нужно знать, чего ожидать от ввода - иначе вы не будете тестировать; вы экспериментируете.
Выполняет код, который печатает любой печатный символ UTF-8:
print(''.join(tuple(chr(l) for l in range(1, 0x10ffff)
if chr(l).isprintable())))
Все символы присутствуют, даже те, которые не обрабатываются используемым шрифтом.
and not chr(l).isspace()
может быть добавлен, чтобы отфильтровать все пробельные символы. (включая вкладку)
Так как Unicode - это всего лишь ряд кодов хорошо, как насчет использования unichr() для получения строки Unicode, соответствующей случайному числу от 0 до 0xFFFF?
(Конечно, это даст только один код, поэтому итерации по мере необходимости)
Вы можете загрузить сайт, написанный на греческом или немецком языке, который использует unicode и передает его вашему коду.
Отвечая на пересмотренный вопрос:
Да, при строгом определении "управляющих символов" - обратите внимание, что вы не будете включать CR, LF и TAB; это то, что вы хотите?
Пожалуйста, подумайте о том, чтобы ответить на мое более раннее приглашение, чтобы сообщить нам, что вы действительно пытаетесь сделать.