나는 텍스트를 사용하고 싶지 않다고 말했지만 B64 사용을 고려해야합니다.따라서 바이너리 변환에서 텍스트로의 이진 변환과 상대적으로 효율적인 바이너리 변환이 가능합니다. 오버 헤드는 1/3입니다. 바이너리 3 바이트마다 4 바이트의 텍스트 값으로 변환됩니다. 텍스트로 변환 한 후 간단한 데이터 스타일 프로토콜을 사용할 수 있습니다. 전송 장치에서는 인코더 만 구현하면됩니다. 아래의 전체 코드를 참조하십시오 :
/********************************************************************/
/* */
/* Functions: */
/* ---------- */
/* TBase64Encode() */
/* TBase64Decode() */
/* TBase64EncodeBlock() */
/* TBase64DecodeBlock() */
/* */
/********************************************************************/
#include "yourstuff.h"
// This table is used to encode 6 bit binary to Base64 ASCII.
static char Base64Map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz/";
// This table is used to decode Base64 ASCII back to 6 bit binary.
static char Base64Decode[]=
{
62, // '+'
99, 99, 99, // **** UNUSED ****
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // ''
99, 99, 99, 99, 99, 99, 99, // **** UNUSED ****
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 'ABCDEFGHIJ'
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'KLMNOPQRST'
20, 21, 22, 23, 24, 25, // 'UVWXYZ'
99, 99, 99, 99, 99, 99, // **** UNUSED ****
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // 'abcdefghij'
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, // 'klmnopqrst'
46, 47, 48, 49, 50, 51 // 'uvwxyz'
};
/** Convert binary data to Base64 data.
*
* @return Size of output buffer if ok, -1 if problem (invalid paramaters).
*
* @param input - Pointer to input data.
* @param size - Number of bytes to encode.
* @param output - Pointer to output buffer.
*
* @note Up to caller to ensure output buffer is big enough. As a rough
* guide your output buffer should be (((size/3)+1)*4) bytes.
*/
int TBase64Encode(const BYTE *input, int size, PSTR output)
{
int i, rc=0, block_size;
while (size>0)
{
if (size>=3)
block_size = 3;
else
block_size = size;
i = TBase64EncodeBlock(input, block_size, output);
if (i==-1)
return -1;
input += 3;
output += 4;
rc += 4;
size -= 3;
}
return rc;
}
/** Convert Base64 data to binary data.
*
* @return Number of bytes in output buffer, negative number if problem
* as follows:
* -1 : Invalid paramaters (bad pointers or bad size).
* -2 : Outside of range value for Base64.
* -3 : Invalid base 64 character.
*
* @param input - Pointer to input buffer.
* @param size - Size of input buffer (in bytes).
* @param output - Pointer to output buffer.
*
* @note Up to caller to ensure output buffer is big enough. As a rough
* guide your output buffer should be (((size/4)+1)*3) bytes.
* NOTE : The input size paramater must be multiple of 4 !!!!
* Note that error codes -2 and -3 essentiallty mean the same
* thing, just for debugging it means something slight different
* to me :-). Calling function can just check for any negative
* response.
*/
int TBase64Decode(CPSTR input, int size, BYTE *output)
{
int output_size=0, i;
// Validate size paramater only.
if (size<=0 || size & 3)
return -1;
while (size>0)
{
i = TBase64DecodeBlock(input, output);
if (i<0)
return i;
output_size += i;
output += i;
input += 4;
size -= 4;
}
return output_size;
}
/** Convert up to 3 bytes of binary data to 4 bytes of Base64 data.
*
* @return 0 if ok, -1 if problem (invalid paramaters).
*
* @param input - Pointer to input data.
* @param size - Number of bytes to encode(1 to 3).
* @param output - Pointer to output buffer.
*
* @note Up to caller to ensure output buffer is big enough (4 bytes).
*/
int TBase64EncodeBlock(const BYTE *input, int size, PSTR output)
{
int i;
BYTE mask;
BYTE input_buffer[3];
// Validate paramaters (rudementary).
if (!input || !output)
return -1;
if (size<1 || size>3)
return -1;
memset(input_buffer, 0, 3);
memcpy(input_buffer, input, size);
// Convert three 8bit values to four 6bit values.
mask = input_buffer[2];
output[3] = mask & 0x3f; // Fourth byte done...
output[2] = mask >> 6;
mask = input_buffer[1] << 2;
output[2] |= (mask & 0x3f); // Third byte done...
output[1] = input_buffer[1] >> 4;
mask = input_buffer[0] << 4;
output[1] |= (mask & 0x3f); // Second byte done...
output[0] = input_buffer[0]>>2; // First byte done...
// TEST
// printf("[%02x,%02x,%02x,%02x]", output[0], output[1], output[2], output[3]);
// Convert 6 bit indices to base64 characters.
for (i=0; i<4; i++)
output[i] = Base64Map[output[i]];
// Handle special padding.
switch (size)
{
case 1:
output[2] = '=';
case 2:
output[3] = '=';
default:
break;
}
return 0;
}
/** Convert 4 bytes of Base64 data to 3 bytes of binary data.
*
* @return Number of bytes (1 to 3) if ok, negative number if problem
* as follows:
* -1 : Invalid paramaters (bad pointers).
* -2 : Outside of range value for Base64.
* -3 : Invalid base 64 character.
*
* @param input - Pointer to input buffer (4 bytes).
* @param output - Pointer to output buufer (3 bytes).
*
* @comm While there may be 1, 2 or 3 output bytes the output
* buffer must be 3 bytes. Note that error codes -2 and -3
* essentiallty mean the same thing, just for debugging it
* means something slight different to me :-). Calling function
* can just check for any negative response.
*/
int TBase64DecodeBlock(CPSTR input, BYTE *output)
{
int i, j;
int size=3;
BYTE mask;
BYTE input_buffer[4];
// Validate paramaters (rudementary).
if (!input || !output)
return -1;
memcpy(input_buffer, input, 4);
// Calculate size of output data.
if (input_buffer[3]=='=')
{
input_buffer[3] = 43;
size--;
}
if (input_buffer[2]=='=')
{
input_buffer[2] = 43;
size--;
}
// Convert Base64 ASCII to 6 bit data.
for (i=0; i<4; i++)
{
j = (int) (input_buffer[i]-43);
if (j<0 || j>79)
return -2; // Invalid char in Base64 data.
j = Base64Decode[j];
if (j==99)
return -3; // Invalid char in Base64 data.
input_buffer[i] = (char) j;
}
// TEST
// printf("[%02x,%02x,%02x,%02x]", input_buffer[0], input_buffer[1], input_buffer[2], input_buffer[3]);
// Convert four 6bit values to three 8bit values.
mask = input_buffer[1] >> 4;
output[0] = (input_buffer[0]<<2) | mask; // First byte done.
if (size>1)
{
mask = input_buffer[1] << 4;
output[1] = input_buffer[2] >> 2;
output[1] |= mask; // Second byte done.
if (size==3)
{
mask = input_buffer[2] << 6;
output[2] = input_buffer[3] | mask; // Third byte done.
}
}
return size;
}
데이터를 보낼 때마다 테이블 헤더를 보내시겠습니까? 나는 그것을 피하려고 노력했다. 필자는 임베디드 장치를 원했고 호스트 컴퓨터는 제한된 테이블 집합에 동의 할 것이고 구조체를 테이블 인덱스로 지정할 것입니다. –
흠. 3 가지 유형의 테이블 데이터가 있다고 가정 해 보겠습니다. [0]을 입력하고 [1]을 입력하고 [2]를 입력하십시오. 장치가 실제로 테이블 데이터를 보내기 전에 연결 시작시 이러한 테이블 구조를 보낼 수 있습니다. 그런 다음 데이터와 함께 * 사용할 테이블 구조 (0, 1 또는 2)를 보낼 수 있습니다. 기본적으로 데이터 자체를 전송하기 전에 모든 설정을 수행하십시오 (설정 종류에 관계없이). – poundifdef
그건 내가 염두에 두었던 것이지만 누군가가 이미 그 코드를 작성했다고 생각합니다. :) –