pickle.load - EOFError:输入输出

Bla*_*x06 7 python base64 pygame pickle python-3.x

我有一个.obj文件,之前,我将图像转换为base64并保存pickle.

问题是当我尝试加载.obj文件时pickle,将代码从base64转换为图像,并加载它pygame.

加载图像的功能:

def mainDisplay_load(self):
    main_folder = path.dirname(__file__)
    img_main_folder = path.join(main_folder, "sd_graphics")

    # loadImg
    self.mainTerminal = pg.image.load(path.join(img_main_folder, self.main_uncode("tr.obj"))).convert_alpha()
Run Code Online (Sandbox Code Playgroud)

解码文件的函数:

def main_uncode(self, object):
    openFile = open(object, "rb")
    str = pickle.load(openFile)
    openFile.close()
    fileData = base64.b64decode(str)
    return fileData
Run Code Online (Sandbox Code Playgroud)

运行代码时出现的错误:

str = pickle.load(openFile)
Run Code Online (Sandbox Code Playgroud)

EOFError:退出输入

我该如何解决?

  • Python版本:3.6.2
  • Pygame版本:1.9.3

更新1

这是我用来创建.obj文件的代码:

import base64, pickle

with open("terminal.png", "rb") as imageFile:
    str = base64.b64encode(imageFile.read())
    print(str)

file_pi = open("tr.obj","wb")
pickle.dump(str,file_pi)
file_pi.close()

file_pi2 = open("tr.obj","rb")
str2 = pickle.load(file_pi2)
file_pi2.close()

imgdata = base64.b64decode(str2)
filename = 'some_image.jpg'  # I assume you have a way of picking unique filenames
with open(filename, 'wb') as f:
    f.write(imgdata)
Run Code Online (Sandbox Code Playgroud)

创建文件后,将加载该文件并创建第二个图像.这是为了检查图像是否相同或转换中是否存在错误.

正如您所看到的,我使用了部分代码来加载图像,但不是保存它,而是将其加载到pygame.这就是错误发生的地方.

更新2

我终于设法解决了.

在主要代码中:

def mainDisplay_load(self):
    self.all_graphics = pg.sprite.Group()
    self.graphics_menu = pg.sprite.Group()

    # loadImg
    self.img_mainTerminal = mainGraphics(self, 0, 0, "sd_graphics/tr.obj")
Run Code Online (Sandbox Code Playgroud)

在包含图形类的库中:

import pygame as pg
import base64 as bs
import pickle as pk
from io import BytesIO as by
from lib.setting import *

class mainGraphics(pg.sprite.Sprite):
    def __init__(self, game, x, y, object):
        self.groups = game.all_graphics, game.graphics_menu
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.object = object
        self.outputGraphics = by()

        self.x = x
        self.y = y

        self.eventType()

        self.rect = self.image.get_rect()
        self.rect.x = self.x * tilesizeDefault
        self.rect.y = self.y * tilesizeDefault

    def eventType(self):
        openFile = open(self.object, "rb")
        str = pk.load(openFile)
        openFile.close()
        self.outputGraphics.write(bs.b64decode(str))
        self.outputGraphics.seek(0)
        self.image = pg.image.load(self.outputGraphics).convert_alpha()
Run Code Online (Sandbox Code Playgroud)

对于为什么我应该做这样的事情,这很简单:

任何有足够动力的攻击者仍然可以轻松搞定

Python是免费和开放的.

一方面,我们有一个人故意去修改和恢复隐藏的数据.但是,如果Python是一种开放式语言,就像更复杂和受保护的语言一样,最有动力的是能够破解游戏或程序并检索相同的数据.

另一方面,我们有一个人只知道基本知识,甚至不知道.在不了解语言或解码文件的情况下无法访问文件的人.

因此,您可以理解,从我的角度来看,解码文件不需要受到保护,不需要受到激励.因为即使有更复杂和受保护的语言,这个有动力的人也能够得到他想要的东西.该保护用于对不懂语言的人.

jsb*_*eno 3

So, if the error you get is indeed "pickle: run out of input", that propably means you messed your directories in the code above, and are trying to read an empty file with the same name as your obj file is.

Actually, as it is, this line in your code:

self.mainTerminal=pg.image.load(path.join(img_main_folder,self.main_uncode
("tr.obj"))).convert_alpha()
Run Code Online (Sandbox Code Playgroud)

Is completly messed up. Just read it and you can see the problem: you are passing to the main_uncode method just the file name, without directory information. And then, if it would by chance have worked, as I have poitned in the comments a while ago, you would try to use the unserialized image data as a filename from where to read your image. (You or someone else had probably thought that main_uncode should write a temporary image file and writ the image data to that, so that Pygame could read it, but as it is, it is just returning the raw image data in a string).

因此,通过修复上述调用并将实际路径传递给main_uncode,并进一步修改它以将临时数据写入文件并返回其路径,将修复上面的代码片段。

第二件事是我根本不明白为什么你需要这个“.obj”文件。如果只是为了“通过模糊实现安全”,希望人们获得您的捆绑文件而无法打开图像,那么这远不是推荐的做法。总结一件事:它会延迟对文件的合法使用(例如,您自己似乎无法使用它),而任何有足够动机的攻击者仍然可以轻松获取它。通过打开图像、base-64 编码并对其进行酸洗,然后执行相反的过程,您基本上执行的是无操作。更重要的是,pickle 文件可以序列化复杂的 Python 对象并将其写入磁盘 - 但图像的 base64 序列化可以直接写入文件,而不需要 pickle。

第三件事:只需使用它 with打开所有文件,而不仅仅是您使用图像库读取的文件,花点时间学习更多有关 Python 的知识。