我在這里搜索了一堆,沒有找到合適的解決方案。這個標題也許有點奇怪,或者不完全準確,但讓我解釋一下。 我的物聯網設備每秒鐘收集一堆資料,我可以用整數串列來表示。下面是一個傳感器讀數行的例子(零并不總是0 btw):
230982 0 4294753011 9 4294198951 1 4294225518 0 0 0 524789 0 934585 0 4 0 0 0 0
在觸發器上,我想把整個表(到那時為止的所有行)發送到我的計算機上。我可以直接將其字串化并連接所有內容,但不知道是否有更有效的編碼/壓縮方法來減少位元組數,無論是在存盤在RAM/閃存中還是在減少傳輸量方面。理想情況下,這可以通過集成功能實作,即不需要外部壓縮庫。我對編碼/壓縮不是很在行,希望你能給我一點提示。
uj5u.com熱心網友回復:
最簡單的解決方案是簡單地將資料以二進制形式轉儲出來。根據你的資料,它可能比字串形式更小或更大,但你不需要在設備上做任何資料處理。
如果您的大部分資料都很小,您可以使用可變長度的資料編碼進行序列化。有幾種方法,但 CBOR 是相當簡單的。
如果您的資料變化很小,您可以只將第一行作為絕對值發送,而將其余各行作為前一行的delta發送。這將導致許多小數字,在前面提到的編碼系統中,這通常是更有效的。
如果沒有任何經驗和外部庫,我不會嘗試實作任何通用的壓縮演算法,除非你絕對需要。找到合適的演算法,將你的資料壓縮得足夠好,并且合理地使用資源,可能會耗費時間。
uj5u.com熱心網友回復:
Zlib/Zstd庫更適合于做通用的壓縮。如果我可以假設你不想使用任何第三方庫,這里有一個手工編碼版本的一些天真的壓縮方法,它節省了輸入字串的一半位元組。
基本想法非常簡單。你的字串最多只有 16 個不同的字符,這些字符可以被映射到 4 位,而不是典型的 8 位。見下面的假設。你可以嘗試base16, base64, base128 編碼,但這是最簡單的。
假設:
- 首先,你將會把你所知道的一切都告訴你。
- 首先,你將把所有的數字轉換成十進制格式的字串。
- 這個字串不會包含任何其他字符,除了
0,1,2,3,4,5,6,7,8,9, ,-,.,空格,和逗號。
============================================================================
#include <stdio.h>/span>
#include <string.h>
#include <stdlib.h>
static inline char map(char c)
{
switch(c) {
case ' ' : return ('/' -'*');
case '': return 0。
default : return c - '*'/span>;
}
return 0;
}
static inline char revmap(char c)
{
switch(c) {
case '' : return 0;
case '/'/span> - '*'/span>: return ' '。
default : return c '*'/span>;
}
return 0;
}
char *compress(const char *s, int len>)
{
int i, j;
char *compr = malloc((len 1)/2 1) 。
j = 0;
for (i = 1; i < len; i = 2)
compr[j ] = map(s[i-1]) << 4 | map(s[i])。
if (i-1 < len)
compr[j ] = map(s[i-1] ) << 4;
compr[j] = ''/span>;
return compr;
}
char *decompress(const *s, int len)
{
int i, j;
char *decompr = malloc(2*len 1) 。
for (i = j = 0; i < len; i ) {
decompr[j ] = revmap((s[i] & 0xf0) >> 4) 。
decompr[j ] = revmap(s[i] & 0xf) 。
}
decompr[j] = ''/span>;
return decompr;
}
int main()
{
const char *input = "230982 0 4294753011 -9 4294198951 -1 4294225518 0 0 0 524789 0 934585 0 4 0 0"。
int plen = strlen(input)。
printf("plain(len=%d): %s
", plen, input)。)
char *compr = compress(input, plen);
int clen = strlen(compr)。
char *decompr = decompress(compr, clen)。
int dlen = strlen(decompr)。
printf("decompressed(len=%d): %s
", dlen, decompr)。)
free(compr)。
free(decompr)。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/332269.html
標籤:
