Как хранить случайные байты в файле, используя кодировку символов? - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь запустить чужую программу Python 2 на Python 3 (с Windows 7).Его цель - генерировать большие факториалы, а затем использовать их как поток случайных чисел.Программа преобразует десятичный факториал в байтовые значения от 0 до 255 и записывает chr(byte value) в файл.Он вычисляет каждый байт, перемещаясь по факториалу в разделах по 8 знаков после запятой.Однако кодировка изменилась с Python 2 на 3 (я не уверен точно, что или почему это важно), и команда chr() не будет работать для любых значений от 128 до 159 (но работают значения от 160 до 255)- программа вызывает "UnicodeEncodeError: 'charmap' codec can't encode character '(the character point)' in position 0: character maps to <undefined>"

Я попытался изменить кодировку файла на "open(filename, "w", encoding="utf-8")", и это успешно записывает все байты.Однако, когда я проверяю свойства случайности файла, они значительно хуже результатов, полученных автором.

Что я должен изменить, чтобы сохранить байты символов, не влияя на случайность данных?

Тестовая программа называется "ent."Из командной строки он принимает файл в качестве аргумента, а затем выводит несколько статистических данных о случайности.Для получения дополнительной информации посетите веб-сайт http://www.fourmilab.ch/random/.

  • Мои результаты для файла из! 500 000, используя open(filename, "w", encoding="utf-8"):

    Entropy = 6.251272 bits per byte.
    
    Optimum compression would reduce the size of this 471812 byte file by 21 percent.
    
    Chi square distribution for 471812 samples is 6545600.65, and randomly
    would exceed this value less than 0.01 percent of the times.
    
    Arithmetic mean value of data bytes is 138.9331 (127.5 = random).
    Monte Carlo value for Pi is 3.173294335 (error 1.01 percent).
    Serial correlation coefficient is 0.162915 (totally uncorrelated = 0.0).
    
  • Авторские результаты для файла из! 500 000:

    Entropy = 7.999373 bits per byte.
    
    Optimum compression would reduce the size of this 313417 byte file by 0 percent.
    
    Chi square distribution for 31347 samples is 272.63, and randomly would
    exceed this value 25.00 percent of the times.
    
    Arithmetic mean value of data bytes is 127.6336 (127.5 = random).
    Monte Carlo value for Pi is 3.149475458 (error 0.25 percent).
    Serial correlation coefficient is -0.001209 (totally uncorrelated = 0.0).
    

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Похоже, что у timakro был ответ (спасибо):

"Чтобы записать бинарный файл, вы должны открыть его в бинарном режиме open (имя файла," wb ") и записать в него объекты, похожие на байты.Например, для записи байта со значением 123: file.write (bytes ([123])). "-timakro

Когда я записываю "bytes([byte value from 0-255])" в файл, он получает ожидаемые оценки случайности с программой ent.Поэтому я изменяю chr() в Python 2 на bytes(), чтобы программа сохраняла байты в Python 3. Кодировка символов не требуется.

0 голосов
/ 21 декабря 2018

Вот вам пример (в Python 3):

# check if the characters are matching Unicode
l1 = [chr(i) for i in range(128, 160)]
print("{}\n".format(l1))

s1 = " ".join(l1)

# display these characters for visual comparison
# before writing them to file
print("INITIAL:")
print(s1)

pf = open("somefile", "wb")
pf.write(s1.encode("utf-8"))
pf.close()

po = open("somefile", "rb")
out = po.read()
po.close()

s2 = out.decode('utf-8')

# display these characters for visual comparison    
# after writing them to file and reading them from it
print("AFTER:")
print(s2)  

, в котором мы тестируем две теории:

  • можно ли кодировать символы (от 128 до 159)
  • можем ли мы записать все данные в двоичном виде в файл?

В первой демонстрации мы ясно видим, что данные совпадают на карте символов Unicode.

Что касается второй теории, мы можем, очевидно, записывать и извлекать двоичные данные в исходном виде, как предполагает вывод:

output

...