pickle.load-eoferor:inpu用完

2024-09-28 05:26:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个.obj文件,在这个文件中,我以前将一个图像转换为base64并用pickle保存。

问题是,当我尝试用pickle加载.obj文件时,将代码从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()

解码文件的函数:

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

运行代码时出现的错误:

str = pickle.load(openFile)

EOFError: Ran out of input

我怎样才能修好它?

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

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

如您所见,我使用了部分代码来加载图像,但它不是保存图像,而是加载到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")

在包含图形类的库中:

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

至于我为什么要做这样的事,很简单:

any attacker with sufficient motivation can still get to it easily

Python是免费开放的。

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

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

所以你可以理解,从我的观点来看,解码文件不需要受到有动机的人的保护。因为即使有更复杂和受保护的语言,有动机的人也能得到他想要的东西。这种保护措施是用来对付不懂这种语言的人的。


Tags: 文件图像selfobjobjectmainloadopen
1条回答
网友
1楼 · 发布于 2024-09-28 05:26:38

因此,如果您得到的错误确实是“pickle:run out of input”,这很可能意味着您弄乱了上面代码中的目录,并试图读取与您的obj文件同名的空文件。

实际上,实际上,代码中的这一行:

self.mainTerminal=pg.image.load(path.join(img_main_folder,self.main_uncode
("tr.obj"))).convert_alpha()

完全搞砸了。只要阅读它,您就可以看到问题:您只向main_uncode方法传递文件名,而不传递目录信息。然后,如果它碰巧能起作用,就像我刚才在评论中指出的那样,您将尝试使用未序列化的图像数据作为从何处读取图像的文件名。(您或其他人可能认为main_uncode应该编写一个临时图像文件并将图像数据写入该文件,以便Pygame可以读取它,但事实上,它只是返回字符串中的原始图像数据)。

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

第二件事是我不明白你为什么需要这个“.obj”文件。如果仅仅是为了“保密而默默无闻”的话,人们会发现你的捆绑文件无法打开图片,这与推荐的做法相去甚远。总结一下:它会延迟文件的合法使用(比如,您自己似乎无法使用它),而任何有足够动机的攻击者仍然可以轻松地使用它。通过打开一个图像,对其进行base-64编码和pickle,并执行相反的过程,您实际上是在执行一个no操作。更重要的是,pickle文件可以序列化并写入磁盘复杂的Python对象,但是可以将映像的base64序列化直接写入文件,而不需要pickle。

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

相关问题 更多 >

    热门问题