UU编码简介

2024-03-18 14:32
文章标签 编码 简介 uu

本文主要是介绍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编码简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822635

相关文章

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Tools】AutoML简介

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 AutoML(自动机器学习)是一种使用机器学习技术来自动化机器学习任务的方法。在大模型中的AutoML是指在大型数据集上使用自动化机器学习技术进行模型训练和优化。

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte

SaaS、PaaS、IaaS简介

云计算、云服务、云平台……现在“云”已成了一个家喻户晓的概念,但PaaS, IaaS 和SaaS的区别估计还没有那么多的人分得清,下面就分别向大家普及一下它们的基本概念: SaaS 软件即服务 SaaS是Software-as-a-Service的简称,意思是软件即服务。随着互联网技术的发展和应用软件的成熟, 在21世纪开始兴起的一种完全创新的软件应用模式。 它是一种通过Internet提供

LIBSVM简介

LIBSVM简介 支持向量机所涉及到的数学知识对一般的化学研究者来说是比较难的,自己编程实现该算法难度就更大了。但是现在的网络资源非常发达,而且国际上的科学研究者把他们的研究成果已经放在网络上,免费提供给用于研究目的,这样方便大多数的研究者,不必要花费大量的时间理解SVM算法的深奥数学原理和计算机程序设计。目前有关SVM计算的相关软件有很多,如LIBSVM、mySVM、SVMLight等,这些

urllib与requests爬虫简介

urllib与requests爬虫简介 – 潘登同学的爬虫笔记 文章目录 urllib与requests爬虫简介 -- 潘登同学的爬虫笔记第一个爬虫程序 urllib的基本使用Request对象的使用urllib发送get请求实战-喜马拉雅网站 urllib发送post请求 动态页面获取数据请求 SSL证书验证伪装自己的爬虫-请求头 urllib的底层原理伪装自己的爬虫-设置代理爬虫coo