javascript - 在 Javascript 中将游戏数据压缩或转换为短字符串密码(然后再返回)
问题描述
(编辑标题是因为我不知道我在寻找什么,而且它具有误导性。)
编辑: 我正在寻找的是二进制到字符串并再次返回。我在下面回答了我自己的问题。)
原帖: 我正在尝试为使用 JavaScript 制作的游戏制作复古风格的密码系统。(例如在旧的 NES 游戏中,它使用字母数字字符来加载您所在的级别或与该级别相关的所有标志。)
到目前为止,我已经生成了一串标志(全是数字),然后稍后通过使用正则表达式对这些标志进行排序,然后将它们放回我的游戏状态对象(其中包含我所有的各种标志的对象)来加载该字符串.
每个标志都是 0-9 之间的数字,每个对象(或标志组)的长度为 8 个字符。(通常带有前导零,因此这些组总是 8 个字符长)
典型的字符串可能如下所示:
var gameStr = "000102340000001000019531";
(shown in groups to illustrate them individually)
00010234
00000010
00019531
(例如 3 组 8 个字符)(24 个字符长)(但游戏结束后可能最终会有超过 25 组 8 个字符)
可以想象,这个数字会变得很长,显然不能作为用户输入的密码。
所以我开始在网上寻找压缩这个数字的方法。
我希望将它压缩成用户可以轻松复制并粘贴到推文或聊天消息中的东西,看起来不太“丑陋”且不太长的东西(我不知道,我在这里不要挑剔,它可能在 6-24 个字符之间?)而且我不介意它是否容易未加密 - 安全性对于这个用例并不重要。如有必要,我愿意更改规则,例如数字的存储方式,每组 4 个标志/数字。我只是在寻找一种方法来使这个数字更小,无论是在数学上还是通过某种压缩算法。
我遇到了两个看似有希望的解决方案,
第一个是名为 lz-string 的 JavaScript 库,它类似于 LZW,但速度更快、更具体,它将字符串压缩成十六进制代码,如下所示:
Input:
000102340000001000019531000102340000001000019531000102340000001000019531
(72 characters)
(9 groups of 8 characters separated just to visualise the numbers in their groups)
00010234
00000010
00019531
00010234
00000010
00019531
00010234
00000010
00019531
Output:
0803c08c199858808e5f807a059c936258190d2c2d438ec6b43c4c5d0080
(spaces removed)(60 characters)
但是正如你所看到的,十六进制仍然很长。
所以我找到的第二个解决方案是这个隐藏在 SO 上的安静答案:
杰米摩根:
将大数转换为公式怎么样:所以我可能使用 4^34 而不是 21312312312
(他们提供了某个数学论坛的链接,但该链接已失效。)
在我看来,这似乎可行,但我不知道如何开始编写这样一个可以做到这一点的函数......(数学真的不是我的强项......)这个这个想法似乎相当于“不煎鸡蛋”的数学。
所以我的问题是,关于如何缩短此数字或将其压缩为压缩数字(或字符串)然后再返回的任何想法?
顺便说一句,我想提一下,我已经花了将近一周的时间在谷歌上搜索并查看此类问题的其他答案,到目前为止,我开始认为这可能是不可能的......如果你有理由相信这是不可能的,请告诉我,这样我就可以停止寻找答案了。我可以轻松地将这些数据保存到浏览器localStorage
并完成它,但我认为密码系统会更真实和有趣挑战以这种方式合并并学习一些有关使用压缩和数字的知识。
预先感谢您的理解以及您可能提供的任何帮助。
解决方案
您要压缩的初始状态来自哪里?我想有三种可能的选择。
这是随机的。这很可能意味着某些代码使用某个值(例如一天中的时间)为伪随机数生成器播种,然后使用它来生成这些值。在这种情况下,您可以获得种子(很可能是一个相当短的数字)并将其用作计算其他所有内容的标识符。确保使用具有明确定义行为的便携式随机数生成器,例如一些Mersenne Twister实现。内置数字生成器的 JavaScript 是实现定义的,因此不符合此要求。
它来自游戏开发者(即您)制作的一些目录。然后将索引混淆到该目录中可能就足够了。
它来自一些用户手动调整值。在这种情况下,您不走运,因为据我了解,问题很可能是任何可能的组合都可以输入。您不能在不丢失信息的情况下将一大组值压缩为一组较小的值。
可能有中间立场。您可以有一个随后手动调整的随机设置,并且作为初始种子加上一些修改的描述将比全套设置短。或者只能按照游戏开发者制定的特定规则进行手动调整,这又会产生一组有限的可能值和可能更短的编码。沿着这些类别思考可能会帮助您分析自己的情况并找到合适的解决方案。
您也可以从信息论的角度来看待这一点。您不能期望用比这些数字更少的信息来编码一系列完全独立且均匀分布的数字,可能以其他一些基数或其他方式表示。如果数据的某些模式使某些组合比其他组合更有可能,您可以压缩数据。你告诉我们的这些模式越多,我们就能提供更好的建议。总的来说,您不能低于源的熵(即游戏状态分布),因此估计这可能会帮助您找到预期的下限。
推荐阅读
- python - Discord.py Bot 响应时间过长
- python - 破折号回调依赖于先前回调中的先前计算和 # 参数的 TypeError
- git - 我可以在不从远程删除它们的情况下删除本地 git 存储库中的文件吗?
- siddhi - 如何让 siddhi 电子邮件接收器工作
- entity-framework-core - 如何通过数据库优先实现 ASP.NET Core 标识
- html - 如何使我的响应式引导图像完美圆润?
- azure-sql-database - 是否可以将 Azure SQL 数据库用作复制发布的源?
- laravel - 社交名流/苹果与 laravel 8 和 jwt-auth
- floating-point - 机器 epsilon 与浮点舍入误差有何关系?
- php - 使用 gd 将两个 images.png 合并到 output.png