压缩js中的0和1的字符串 [英] compressing a string of 0's and 1's in js

查看:381
本文介绍了压缩js中的0和1的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发John Conway的js游戏。我有游戏工作(查看这里),我正在开发额外的功能,如共享你的网格/游戏给你的朋友。为此,我将网格的值(如果单元格是活的还是死的)提取为0和1的长字符串。

I'm currently working on John Conway's Game of Life in js. I have the game working (view here) and i'm working on extra functionalities such as sharing your "grid / game" to your friends. To do this i'm extracting the value's of the grid (if the cell is alive or dead) into a long string of 0's and 1's.

这个字符串有一个变量长度,因为网格不总是相同的大小。例如:

This string has a variable length since the grid is not always the same size. for example:


网格1的长度和宽度为30 =>所以字符串的长度为900

grid 1 has a length and width of 30 => so the string's length is 900

grid 2的长度和宽度为50 =>所以字符串的长度为2500

grid 2 has a length and width of 50 => so the string's length is 2500



/ h1>

正如你可以看到,这些字符串的0和1的方式太长,无法复制和共享。

The problem

As you can see these string's of 0's and 1's are way too long to copy around and share.

然而,我似乎无法想出一个代码,可以压缩一个字符串这么长的一个容易处理一个。

However hard i try I don't seem to be able to come up with a code that would compress a string this long to a easy to handle one.

有关如何压缩(并解压缩)此内容的任何想法?

为网格尺寸1x1到100x100写下每个可能的网格选项,并给它们一个键/参考以用作可共享代码。用手工做会是疯狂,但也许任何人都有一个想法如何创建一个算法,可以做到这一点?

I have considered simply writing down every possible grid option for the gird sizes 1x1 to 100x100 and giving them a key/reference to use as sharable code. Doing that by hand would be madness but maybe any of you has an idea on how to create an algorithm that can do this?

GitHub存储库

推荐答案

如果它不是很明显,你试图存储的字符串看起来像一个二进制字符串。

In case it wasn't already obvious, the string you're trying to store looks like a binary string.

二进制是 base-2 。这基本上意味着有两个字符用于保持计数。通常,我们习惯使用 base-10 (十进制字符)。在计算机科学中,十六进制系统( base-16 )也被广泛使用。

Binary is a number in base-2. This essentially means that there are two characters being used to keep count. Normally we are used to count with base-10 (decimal characters). In computer science the hexadecimal system (base-16) is also widely being used.

因为你不是把位存储为位而是作为字节存储(使用 var a = 0b1100001;

Since you're not storing the bits as bits but as bytes (use var a = 0b1100001; if you ever wish to store them like bits) the 'binary' you wish to store just takes as much space as any other random string with the same length.

因为我们希望存储的二进制文件只占用与任何其他长度相同的随机字符串一样多的空间。你使用二进制系统每个位置只有2个可能的值。使用十六进制值时,单个位置最多可以保留16个可能的值。这对于紧凑地存储数据已经是一个很大的改进。例如 0b11111111 0xff 都代表十进制数255.

Since you're using the binary system each position just has 2 possible values. When using the hexadecimal value a single position can hold up to 16 possible values. This is already a big improvement when it comes to storing the data compactly. As an example 0b11111111 and 0xff both represents the decimal number 255.

在你的情况下,你会刮掉每8个字节6个字节,你必须存储。最后,你会被一个字符串只是原来的字符串长度的四分之一。

In your situation that'd shave 6 bytes of every 8 bytes you have to store. In the end you'd be stuck with a string just 1/4th of the length of the original string.

本质上,我们要做的是将您存储的字符串解释为二进制并检索十六进制值。幸运的是,JavaScript具有实现这样的功能:

Essentially what we want to do is to interpret the string you store as binary and retrieve the hexadecimal value. Luckily JavaScript has built in functionality to achieve stuff like this:

var bin =
  '1110101110100011' +
  '0000101111100001' +
  '1010010101011010' +
  '0000110111011111' +
  '1111111001010101' +
  '0111000011100001' +
  '1011010100110001' +
  '0111111110010100' +
  '0111110110100101' +
  '0000111101100111' +
  '1100001111011100' +
  '0101011100001111' +
  '0110011011001101' +
  '1000110010001001' +
  '1010100010000011' +
  '0011110000000000';

var returnValue = '';

for (var i = 0; i < parseInt(bin.length / 8); i++) {
    returnValue += parseInt(bin.substr(i*8, 8), 2).toString(16);
}

console.log(bin.length); // Will return 265
console.log(returnValue.length); // Will return 64



我们在说解析这个字符串,数字并将其存储为十六进制字符串。

We're saying "parse this string and interpret it like a base-2 number and store it as a hexadecimal string".

解码几乎是相同的。

A此代码正确工作的先决条件是二进制长度可以除以8.参见以下示例:

A prerequisite for this code to work correctly is that the binary length is dividable by 8. See the following example:

parseInt('00011110', 2).toString(16); // returns '1e'
parseInt('1e', 16).toString(2); // returns '11110'
// Technically both representations still have the same decimal value

解码时,您应该添加前导零,直到您有一个完整的字节(8位)。

When decoding you should add leading zeros until you have a full byte (8 bits).

如果您必须存储的位置不能被8除,例如,添加填充并在输出字符串的前面添加一个数字以标识要截断的位置。

In case the positions you have to store are not dividable by 8 you can, for example, add padding and add a number to the front of the output string to identify how much positions to strip.

要获得更短的字符串,您可以构建一个包含265个字符的查找表,在其中搜索与特定位置相关联的字符。 ()因为您仍然将十六进制值存储为字符串。)很遗憾, ASCII UTF-8 编码适用于此,

To get even shorter strings you can build a lookup table with 265 characters in which you search for the character associated with the specific position. (This works because you're still storing the hexadecimal value as a string.) Sadly neither the ASCII nor the UTF-8 encodings are suited for this as there are blocks with values which have no characters defined.

它可能如下所示:

// Go fill this array until you have 265 values within it.
var lookup = ['A', 'B', 'C', 'D'];
var smallerValue = lookup[0x00];

这样,您可以在单个位置拥有265个可能的值,

This way you can have 265 possible values at a single position, AND you have used your byte to the fullest.

请注意,这里不会发生真正的压缩。我们更倾向于使用数据类型来更有效地使用当前的用例。

Please note that no real compression is happening here. We're rather utilising data types to be used more efficiently for your current use case.

这篇关于压缩js中的0和1的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆