Расшифровка файла в потоке и чтение потока в pandas (hdf или stata)

Обзор того, что я пытаюсь сделать. У меня есть зашифрованные версии файлов, которые мне нужно прочитать в pandas. По двум причинам гораздо лучше дешифровать в поток, а не файл, так что это мой интерес ниже, хотя я также пытаюсь дешифровать файл как промежуточный шаг (но это также не работает).

Я могу заставить это работать для csv, но не для hdf или stata (я бы принял ответ, который работает либо для hdf, либо для stata, хотя ответ может быть одинаковым для обоих, и именно поэтому я сочетая в одном вопросе).

Код для шифрования / дешифрования файлов берется из другого вопроса stackoverflow (которого я не могу найти в данный момент).

import pandas as pd import io from Crypto import Random from Crypto.Cipher import AES def pad(s): return s + b"\0" * (AES.block_size - len(s) % AES.block_size) def encrypt(message, key, key_size=256): message = pad(message) iv = Random.new().read(AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) return iv + cipher.encrypt(message) def decrypt(ciphertext, key): iv = ciphertext[:AES.block_size] cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(ciphertext[AES.block_size:]) return plaintext.rstrip(b"\0") def encrypt_file(file_name, key): with open(file_name, 'rb') as fo: plaintext = fo.read() enc = encrypt(plaintext, key) with open(file_name + ".enc", 'wb') as fo: fo.write(enc) def decrypt_file(file_name, key): with open(file_name, 'rb') as fo: ciphertext = fo.read() dec = decrypt(ciphertext, key) with open(file_name[:-4], 'wb') as fo: fo.write(dec) 

И вот моя попытка расширить код для расшифровки потока, а не файла.

 def decrypt_stream(file_name, key): with open(file_name, 'rb') as fo: ciphertext = fo.read() dec = decrypt(ciphertext, key) cipherbyte = io.BytesIO() cipherbyte.write(dec) cipherbyte.seek(0) return cipherbyte 

Наконец, вот примерная программа с выборочными данными, пытающимися сделать эту работу:

 key = 'this is an example key'[:16] df = pd.DataFrame({ 'x':[1,2], 'y':[3,4] }) df.to_csv('test.csv',index=False) df.to_hdf('test.h5','test',mode='w') df.to_stata('test.dta') encrypt_file('test.csv',key) encrypt_file('test.h5',key) encrypt_file('test.dta',key) decrypt_file('test.csv.enc',key) decrypt_file('test.h5.enc',key) decrypt_file('test.dta.enc',key) # csv works here but hdf and stata don't # I'm less interested in this part but include it for completeness df_from_file = pd.read_csv('test.csv') df_from_file = pd.read_hdf('test.h5','test') df_from_file = pd.read_stata('test.dta') # csv works here but hdf and stata don't # the hdf and stata lines below are what I really need to get working df_from_stream = pd.read_csv( decrypt_stream('test.csv.enc',key) ) df_from_stream = pd.read_hdf( decrypt_stream('test.h5.enc',key), 'test' ) df_from_stream = pd.read_stata( decrypt_stream('test.dta.enc',key) ) 

К сожалению, я не думаю, что могу больше сжать этот код и до сих пор иметь полный пример.

Опять же, я надеюсь, что у вас будет все 4 нерабочие строки выше (файл и поток для hdf и stata), но я рад принять ответ, который работает только для потока hdf или потока stata.

Кроме того, я открыт для других альтернатив шифрования, я просто использовал какой-то существующий код на основе pycrypto, который я нашел здесь на SO. Моя работа явно требует 256-битного AES, но помимо этого я открыт, поэтому это решение не должно основываться конкретно на библиотеке pycrypto или конкретном примере кода выше.

Информация о моей настройке:

 python: 3.4.3 pandas: 0.17.0 (anaconda 2.3.0 distribution) mac os: 10.11.3 

One Solution collect form web for “Расшифровка файла в потоке и чтение потока в pandas (hdf или stata)”

Самой большой проблемой является метод заполнения / разборки. Он предполагает, что нулевой символ не может быть частью фактического содержимого. Поскольку файлы stata/hdf являются двоичными, безопаснее использовать пэд, используя количество дополнительных байтов, которые мы используем, закодированные как символ. Этот номер будет использоваться во время разборки.

Также на этот раз read_hdf не поддерживает чтение из файла, подобного объекту, даже если документация API утверждает это. Если мы ограничимся форматом stata , следующий код выполнит то, что вам нужно:

 import pandas as pd import io from Crypto import Random from Crypto.Cipher import AES def pad(s): n = AES.block_size - len(s) % AES.block_size return s + n * chr(n) def unpad(s): return s[:-ord(s[-1])] def encrypt(message, key, key_size=256): message = pad(message) iv = Random.new().read(AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) return iv + cipher.encrypt(message) def decrypt(ciphertext, key): iv = ciphertext[:AES.block_size] cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(ciphertext[AES.block_size:]) return unpad(plaintext) def encrypt_file(file_name, key): with open(file_name, 'rb') as fo: plaintext = fo.read() enc = encrypt(plaintext, key) with open(file_name + ".enc", 'wb') as fo: fo.write(enc) def decrypt_stream(file_name, key): with open(file_name, 'rb') as fo: ciphertext = fo.read() dec = decrypt(ciphertext, key) cipherbyte = io.BytesIO() cipherbyte.write(dec) cipherbyte.seek(0) return cipherbyte key = 'this is an example key'[:16] df = pd.DataFrame({ 'x': [1,2], 'y': [3,4] }) df.to_stata('test.dta') encrypt_file('test.dta', key) print pd.read_stata(decrypt_stream('test.dta.enc', key)) 

Вывод:

  index xy 0 0 1 3 1 1 2 4 

В python 3 вы можете использовать следующие unpad , unpad версии:

 def pad(s): n = AES.block_size - len(s) % AES.block_size return s + bytearray([n] * n) def unpad(s): return s[:-s[-1]] 
  • Факториальный расчет с использованием Python
  • Создание мастера в Tkinter
  • pip throws TypeError: parse () получил неожиданный аргумент ключевого слова 'transport_encoding' при попытке установить новые пакеты
  • url_for с _external = True на heroku не добавляет имя сервера в URL-адрес
  • Плавающая точка до 16 бит Twos Complement Binary, Python
  • ошибки округления в Python floor division
  • Python: Pandas, текстовый файл в DataFrame
  • Преобразование CSV в YAML, с Unicode?
  • Настройка CSV-данных: добавление ячеек в предыдущую строку, слияние ячеек, содержащих определенную строку
  • Могу ли я установить Python 3.x и 2.x на тот же компьютер?
  • Tensorflow Нет модуля с именем _pywrap
  • Python - лучший язык программирования в мире.