本文主要是介绍UU编码简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、简介
uu 编码 将3字节BIN数据转换成4字节可打印ASCII字符。
uuencode 编码方式用于将任意的二进制文件转换为文本文件,比如email.转换后的文件中仅包含可打印字符.
uuencode 运算法则将连续的 3字节编码转换成 4字节(8-bit 到 6-bit)的可打印字符.
2、示例
从二进制文件中读取 3字节的数据, 表示如下(a7 表示 a字节的第 7位):
a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0
转换它们到4字节里为如下所示:
0 0 a7a6a5a4a3a2 0 0 a1a0b7b6b5b4 0 0 b3b2b1b0c7c6 0 0 c5c4c3c2c1c0
然后, 每个字节再加 0x20转换为可打印的字符.
注意: 如果是一个 0字节那它应该被转换为0x60而不是0x20, 因为(前引用'`')优于 0x20(空格' ').
例如: 从文件中读取的 3字节如下:
14 0F A8
00010100 00001111 10101000
转换为 6-bit:
000101 000000 111110 101000
每字节高两位补 0后为:
00000101 00000000 00111110 00101000
最后每字节再加 0x20,则 4字节输出应该为:
25 60 5E 48
注意: 00字节被转换为 0x60而不是 0x20.
因此, 在一个 uuencoded文件中仅包含字符 0x21 '!'到 0x60 '`',它们都是可打印和可被 email传送的.
这个转换过程也意味着 uuencoded 文件要比原文件大 33%的.
3、 编码与解码
3.1编码
outbuf [4] 输出 uu编码数据.
inbytep [3] 输入二进制数据.
#define ENCODE_BYTE(b) (((b) == 0) ? 0x60 : ((b) + 0x20))
outbuf [0] = ENCODE_BYTE ((inbytep [0] & 0xFC) >> 2);
outbuf [1] = ENCODE_BYTE (((inbytep [0] & 0x03) << 4) + ((inbytep [1] & 0xF0) >> 4));
outbuf [2] = ENCODE_BYTE (((inbytep [1] & 0x0F) << 2) + ((inbytep [2] & 0xC0) >> 6));
outbuf [3] = ENCODE_BYTE (inbytep [2] & 0x3F);
3.2 解码
linep [4] 输入 uu编码数据.
outbyte [3] 输出二进制数据.
#define DECODE_BYTE(b) ((b == 0x60) ? 0 : b - 0x20)
outbyte [0] = DECODE_BYTE (linep [0]);
outbyte [1] = DECODE_BYTE (linep [1]);
outbyte [0] <<= 2;
outbyte [0] |= (outbyte [1] >> 4) & 0x03;
outbyte [1] <<= 4;
outbyte [2] = DECODE_BYTE (linep [2]);
outbyte [1] |= (outbyte [2] >> 2) & 0x0F;
outbyte [2] <<= 6;
outbyte [2] |= DECODE_BYTE (linep [3]) & 0x3F;
4、源码
4.1编码
#include "stdio.h"
#include "stdlib.h"
#define MAX_LINELEN 45
#define ENCODE_BYTE(b) (((b) == 0) ? 0x60 : ((b) + 0x20))
typedef unsigned char BYTE;
int main (int argc, char *argv [])
{
FILE *infile = NULL;
FILE *outfile = NULL;
int linelen;
int linecnt;
BYTE inbuf [MAX_LINELEN];
BYTE *inbytep;
char outbuf [5];
if (argc != 3)
{
fprintf (stderr, "Syntax: uuencode <infile> <outfile>\n");
exit (1);
}
/* Try and open the input file (binary) */
infile = fopen (argv[1], "rb");
if (infile == NULL)
{
fprintf (stderr, "uuencode: Couldn't open input file %s\n", argv[1]);
exit (1);
}
/* Try and open the output file (text) */
outfile = fopen (argv[2], "wt");
if (outfile == NULL)
{
fprintf (stderr, "uuencode: Couldn't open output file %s\n", argv[2]);
exit (1);
}
/* Write the 'begin' line, giving it a mode of 0600 */
fprintf (outfile, "begin 600 %s\n", argv[1]);
do
{
/* Read a line from input file */
linelen = fread (inbuf, 1, MAX_LINELEN, infile);
/* Write the line length byte */
fputc (ENCODE_BYTE (linelen), outfile);
/* Encode the line */
for (linecnt = linelen, inbytep = inbuf;
linecnt > 0;
linecnt -= 3, inbytep += 3)
{
/* Encode 3 bytes from the input buffer */
outbuf [0] = ENCODE_BYTE ((inbytep [0] & 0xFC) >> 2);
outbuf [1] = ENCODE_BYTE (((inbytep [0] & 0x03) << 4) + ((inbytep [1] & 0xF0) >> 4));
outbuf [2] = ENCODE_BYTE (((inbytep [1] & 0x0F) << 2) + ((inbytep [2] & 0xC0) >> 6));
outbuf [3] = ENCODE_BYTE (inbytep [2] & 0x3F);
outbuf [4] = '\0';
/* Write the 4 encoded bytes to the file */
fprintf (outfile, "%s", outbuf);
}
fprintf (outfile, "\n");
} while (linelen != 0);
/* Write the 'end' marker */
fprintf (outfile, "end\n");
/* Tidy up and return */
fclose (infile);
fclose (outfile);
return 0;
}
4.2 解码
/*
* uudecode.c -
* Simple uudecode utility
* Jim Cameron, 1997
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* We all hate magic numbers! */
#define LINE_BUF_SIZE 256
/* Decode a byte */
#define DECODE_BYTE(b) ((b == 0x60) ? 0 : b - 0x20)
typedef unsigned char BYTE;
int main (int argc, char *argv[])
{
FILE *infile = NULL;
FILE *outfile = NULL;
char linebuf [LINE_BUF_SIZE];
char *linep = NULL;
char *tempcp = NULL;
int linelen = 0;
int linecnt = 0;
char outfname [LINE_BUF_SIZE];
BYTE outbyte [3];
/* Check that we have the right number of arguments */
if (argc != 2)
{
fprintf (stderr, "Syntax: uudecode <filename>\n");
exit (1);
}
/* Open the input file */
infile = fopen (argv[1], "rt");
if (infile == NULL)
{
fprintf (stderr, "uudecode: Couldn't open file %s\n", argv[1]);
exit (1);
}
/* uu-encoded files always have a 'begin' marker, so go and look for this */
for (;;)
{
/* Read a line */
if (fgets (linebuf, LINE_BUF_SIZE, infile) == NULL)
{
fprintf (stderr, "uudecode: Not a valid uu-encoded file\n");
exit (1);
}
/* See if it is the 'begin' marker */
if ((strncmp (linebuf, "begin", 5) == 0) && isspace (linebuf[5]))
{
break;
}
}
/* If we have reached this point, we have found a begin marker */
linep = linebuf + 5;
/* Next comes the mode, which we ignore */
while (isspace (*linep))
{
linep++;
}
if (*linep == '\0')
{
fprintf (stderr, "uudecode: Not a valid uu-encoded file\n");
exit (1);
}
while (isdigit (*linep))
{
linep++;
}
while (isspace (*linep))
{
linep++;
}
if (*linep == '\0')
{
fprintf (stderr, "uudecode: Not a valid uu-encoded file/n");
exit (1);
}
/* The rest of the begin line is the output file name */
strcpy (outfname, linep);
tempcp = outfname;
while (!isspace (*tempcp) && (*tempcp != '\0'))
{
tempcp++;
}
*tempcp = '\0';
/* Now open the output file */
outfile = fopen (outfname, "wb");
if (outfile == NULL)
{
fprintf (stderr, "uudecode: Couldn't open output file %s\n", outfname);
exit (1);
}
/* Now for the uu-decode proper */
do
{
if (fgets (linebuf, LINE_BUF_SIZE, infile) == NULL)
{
fprintf (stderr, "uudecode: Read error\n");
exit (1);
}
/* The first byte of the line represents the length of the DECODED line */
linelen = DECODE_BYTE (linebuf[0]);
linep = linebuf + 1;
for (linecnt = linelen; linecnt > 0; linecnt -= 3, linep += 4)
{
/* Check for premature end-of-line */
if ((linep[0] == '\0') || (linep[1] == '\0') ||
(linep[2] == '\0') || (linep[3] == '\0'))
{
fprintf (stderr, "uudecode: Error in encoded block\n");
exit (1);
}
/* Decode the 4-byte block */
outbyte[0] = DECODE_BYTE (linep[0]);
outbyte[1] = DECODE_BYTE (linep[1]);
outbyte[0] <<= 2;
outbyte[0] |= (outbyte[1] >> 4) & 0x03;
outbyte[1] <<= 4;
outbyte[2] = DECODE_BYTE (linep[2]);
outbyte[1] |= (outbyte[2] >> 2) & 0x0F;
outbyte[2] <<= 6;
outbyte[2] |= DECODE_BYTE (linep[3]) & 0x3F;
/* Write the decoded bytes to the output file */
if (linecnt > 3)
{
if (fwrite (outbyte, 1, 3, outfile) != 3)
{
fprintf (stderr, "uudecode: Error writing to output file\n");
exit (1);
}
}
else
{
if (fwrite (outbyte, 1, linecnt, outfile) != linecnt)
{
fprintf (stderr, "uudecode: Error writing to output file\n");
exit (1);
}
linecnt = 3;
}
}
} while (linelen != 0);
/* All is ok, tidy up and exit */
fclose (infile);
fclose (outfile);
return 0;
}
这篇关于UU编码简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!