【问题标题】:How to turn pickle output into an unreadable format如何将泡菜输出变成不可读的格式
【发布时间】:2016-12-06 21:39:35
【问题描述】:

将 pickle 库与我创建的一些类一起使用时,输出对用户来说相当容易阅读。例如,如果我有一个名为 saves 的填充,并将我的所有类数据保存到其中的 .save 文件中,当使用文本编辑器打开文件时,您可以隐约看到所有变量,无需太多努力,将它们更改为想要的结果。

这是我用pickle创建的保存文件中的一个sn-p(这是一个游戏):

S'Strength'
p4
I5
sS'Health'
p8
I100

在此,“健康”的值为 100,“强度”为 5,如果用户要编辑保存文件(因为它将保存在本地),他们可以轻松更改他们想要的任何变量为了作弊。

因为我正在创建一个游戏,其中保存游戏是我计划实现的功能之一,这已成为一个问题。

我确实考虑过使用加密,但使用第二个外部库是最后的手段,因为它可能非常乏味,所以我想知道是否有其他方法可以做到这一点,或者 pickle 是否带有内置的在功能上(经过研究我没有看到)。

【问题讨论】:

  • 如果是单人游戏,他们想作弊,让他们。如果是多人游戏并且他们想作弊,这不会阻止他们。
  • 我确实考虑过这个选项,但我至少希望它更难一点,因为有些小众社区会喜欢狩猎,它也可以起到威慑作用。
  • 作为“威慑剂”,意义不大。持久的玩家可以在 pdb 中单步执行您的程序,并准确找出您是如何混淆保存的。现在,如果你只是想取悦那些想这样做的人,那完全没问题,但要清楚你想在这里做什么。
  • 这是一个很好的观点,公平地说,这样做只会增加额外的任务,在一个非常大的程序中,这只会浪费处理能力
  • 让它在其他地方保存输出的哈希值,并将其与加载保存进行比较 -> 如果不同,就说它“损坏”

标签: python python-3.x pickle


【解决方案1】:

您可以简单地对数据进行签名,然后在读取时对其进行身份验证,而不是试图让您的数据不可读

保存

这里使用hmac 来计算哈希。然后我们将哈希值与数据一起保存:

import hmac, pickle

# pickle the data
pickled = pickle.dumps(data)
digest =  hmac.new("some-shared-key", pickled, 
                   digestmod=<my choice of hasher>
                   ).hexdigest()

# now save the hashed digest and the pickled data
with open("some-file", "wb") as f:
    # save these in some way you can distinguish them when you read them
    print(digest, file=f)
    print(pickled, file=f)

加载中

为了验证数据,我们重新计算腌制数据的摘要,并将其与旁边保存的摘要进行比较。

import hmac, pickle

with open("some-file", "rb") as f:
    digest = f.readline()
    pickled = f.read()

# confirm integrity
recomputed = hmac.new("some-shared-key", pickle, 
                       digestmod=<my choice of hasher>
                      ).hexdigest()
if not compare_digest(digest, recomputed):
    raise SomeOneIsCheatingOhNoException

【讨论】:

  • 这实际上是我没有想到的,它也是保护保存文件的好主意,并且可能是我场景中的最佳选择,谢谢。
  • 明确一点:这是可以规避的,只是这样做更具挑战性。
  • 我可以理解,用户所要做的就是根据新数据重新计算哈希,然后编辑保存的哈希
  • @Ashmoreinc 是的...不过他们需要您的代码中的共享密钥(这并不难找到...)
  • 不管怎样,它会变得更难,普通用户不太可能理解如何做到这一点,所以从长远来看,这是最好的方法。
【解决方案2】:

稍微混淆的一个想法是简单的十六进制转换或您选择的编码。对于十六进制我会做(+12 是我猜的随机噪声)

mylist_obf = map(lambda item:int(item.encode('hex'))+12,mylist)

通过反向操作获取原始数据

my_original_list = map(lambda item: str(int(item)-12).decode('hex'),mylist_obf)

请注意,这是非常不安全的,只会阻止玩家认为它实际上是加密的。

【讨论】:

  • 这是个好主意,它本身并不能完全保护输出,但它确实可以作为“欺骗”游戏的额外步骤,如果他们愿意这样做,我怀疑还有很多事情会阻止他们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
相关资源
最近更新 更多