我有一个.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
我怎样才能修好它?
这是我用来创建.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
。这就是错误发生的地方。
我终于解决了。
在主代码中:
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是一种开放语言,就像使用更复杂和受保护的语言一样,最有动机的人能够破解游戏或程序并检索相同的数据。
另一方面,我们有一个人只知道基本知识,甚至不知道。一个在不了解语言或解码文件的情况下无法访问文件的人。
所以你可以理解,从我的观点来看,解码文件不需要受到有动机的人的保护。因为即使有更复杂和受保护的语言,有动机的人也能得到他想要的东西。这种保护措施是用来对付不懂这种语言的人的。
因此,如果您得到的错误确实是“pickle:run out of input”,这很可能意味着您弄乱了上面代码中的目录,并试图读取与您的
obj
文件同名的空文件。实际上,实际上,代码中的这一行:
完全搞砸了。只要阅读它,您就可以看到问题:您只向
main_uncode
方法传递文件名,而不传递目录信息。然后,如果它碰巧能起作用,就像我刚才在评论中指出的那样,您将尝试使用未序列化的图像数据作为从何处读取图像的文件名。(您或其他人可能认为main_uncode
应该编写一个临时图像文件并将图像数据写入该文件,以便Pygame可以读取它,但事实上,它只是返回字符串中的原始图像数据)。然后,通过修复上述调用并将实际路径传递给
main_uncode
,并进一步修改它以将临时数据写入文件并返回其路径,将修复上述代码片段。第二件事是我不明白你为什么需要这个“.obj”文件。如果仅仅是为了“保密而默默无闻”的话,人们会发现你的捆绑文件无法打开图片,这与推荐的做法相去甚远。总结一下:它会延迟文件的合法使用(比如,您自己似乎无法使用它),而任何有足够动机的攻击者仍然可以轻松地使用它。通过打开一个图像,对其进行base-64编码和pickle,并执行相反的过程,您实际上是在执行一个no操作。更重要的是,pickle文件可以序列化并写入磁盘复杂的Python对象,但是可以将映像的base64序列化直接写入文件,而不需要pickle。
第三件事:只需使用
with
打开所有文件,而不仅仅是使用图像库阅读的文件,花点时间了解更多关于Python的知识。相关问题 更多 >
编程相关推荐