⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_encode.c

📁 算法源代码比较经典
💻 C
字号:
/*
	R_ENCODE.C - RFC 1113 encoding and decoding routines

	Copyright (c) J.S.A.Kapp 1994 - 1995.

	RSAEURO - RSA Library compatible with RSAREF(tm) 2.0.

	All functions prototypes are the Same as for RSAREF(tm).
	To aid compatiblity the source and the files follow the
	same naming comventions that RSAREF(tm) uses.  This should aid
	direct importing to your applications.

	This library is legal everywhere outside the US.  And should
	NOT be imported to the US and used there.

	All Trademarks Acknowledged.

	Based in a similar form to the PGP RFC 1113 coding routines.

	Revision history
		0.90 First revision, based purely on using macros to
		en/decode data to RFC 1113 standard.

		0.91 Initial revision using current system.

        0.92 Third revision, fixed minor bugs in rev. 0.91
		and better comments updated, plus code layout.

        1.02 Fourth revision, fixed bug in R_EncodePEMBlock
        reported by Wang Wei Jun <wangw@iti.gov.sg>.
*/

#include "rsaeuro.h"

/* RFC 1113 encoding:

	 Value Encoding  Value Encoding  Value Encoding  Value Encoding
			 0 A            17 R            34 i            51 z
			 1 B            18 S            35 j            52 0
			 2 C            19 T            36 k            53 1
			 3 D            20 U            37 l            54 2
			 4 E            21 V            38 m            55 3
			 5 F            22 W            39 n            56 4
			 6 G            23 X            40 o            57 5
			 7 H            24 Y            41 p            58 6
			 8 I            25 Z            42 q            59 7
			 9 J            26 a            43 r            60 8
			10 K            27 b            44 s            61 9
			11 L            28 c            45 t            62 +
			12 M            29 d            46 u            63 /
			13 N            30 e            47 v
			14 O            31 f            48 w         (pad) =
			15 P            32 g            49 x
			16 Q            33 h            50 y
*/

/*
	PEM routines.
	This converts a binary file into printable ASCII characters, in a
	radix-64 form mostly compatible with the PEM RFC 1113 format.
	This makes it easier to send encrypted files over a 7-bit channel.
*/

/* ENC is the basic 1 character encoding function to make a char printing */

#define ENC(c) ((int)bintoasc[((c) & 077)])
#define PAD             '='

/* Index this array by a 6 bit value to get the character corresponding
	 to that value. */

static unsigned char bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz0123456789+/";

/* Index this array by a 7 bit value to get the 6-bit binary field
	 corresponding to that value.  Any illegal characters return high bit set. */

static unsigned char asctobin[] = {
	0200,0200,0200,0200,0200,0200,0200,0200,
	0200,0200,0200,0200,0200,0200,0200,0200,
	0200,0200,0200,0200,0200,0200,0200,0200,
	0200,0200,0200,0200,0200,0200,0200,0200,
	0200,0200,0200,0200,0200,0200,0200,0200,
	0200,0200,0200,0076,0200,0200,0200,0077,
	0064,0065,0066,0067,0070,0071,0072,0073,
	0074,0075,0200,0200,0200,0200,0200,0200,
	0200,0000,0001,0002,0003,0004,0005,0006,
	0007,0010,0011,0012,0013,0014,0015,0016,
	0017,0020,0021,0022,0023,0024,0025,0026,
	0027,0030,0031,0200,0200,0200,0200,0200,
	0200,0032,0033,0034,0035,0036,0037,0040,
	0041,0042,0043,0044,0045,0046,0047,0050,
	0051,0052,0053,0054,0055,0056,0057,0060,
	0061,0062,0063,0200,0200,0200,0200,0200
};

static void encode PROTO_LIST((unsigned char [4], unsigned char [3], int ));

/* This will always returns 0.  It is an int function for future compatibility,
	 done to provide compatibility with RSAREF(tm). */

int R_EncodePEMBlock(encodedBlock, encodedBlockLen, block, blockLen)
unsigned char *encodedBlock;    /* encoded block */
unsigned int *encodedBlockLen;  /* length of encoded block */
unsigned char *block;           /* block */
unsigned int blockLen;          /* length of block */
{
	unsigned int i, lastLen;

	if(blockLen < 1) {
		*encodedBlockLen = 0;
		return (IDOK);
	}

	*encodedBlockLen = 0;

        /* Bug Fixed By SK 02/09/95 */
    for (i = 0, lastLen = blockLen; i < blockLen; i += 3) {
        encode(&encodedBlock[4*i/3], &block[i], (lastLen >= 3 ? 3 : lastLen));
        lastLen -= 3;
		*encodedBlockLen += 4;
	}

	return(IDOK);
}

int R_DecodePEMBlock (outbuf, outlength, inbuf, inlength)
unsigned char *outbuf;          /* block */
unsigned int *outlength;        /* length of block */
unsigned char *inbuf;           /* encoded block */
unsigned int inlength;          /* length of encoded block */
{
	unsigned char *bp;
	int     length;
	unsigned int c1,c2,c3,c4;
	register int j;

	if(inlength % 4)
		return (RE_ENCODING);

	if(inlength < 1) {
		*outlength = 0;
		return (IDOK);
	}


	length = 0;
	bp = (unsigned char *)inbuf;

	/* FOUR input characters go into each THREE output charcters */

	while(inlength > 0) {
		if(*bp&0x80 || (c1=asctobin[*bp])&0x80)
			return(RE_ENCODING);
		++bp;
		if(*bp&0x80 || (c2=asctobin[*bp])&0x80)
			return(RE_ENCODING);
		if(*++bp == PAD){
			c3 = c4 = 0;
			length += 1;
			if(*++bp != PAD)
				return(RE_ENCODING);
		}
		else if(*bp&0x80 || (c3=asctobin[*bp])&0x80)
				return(RE_ENCODING);
		else {
			if(*++bp == PAD) {
				c4 = 0;
				length += 2;
			}
			else if (*bp&0x80 || (c4=asctobin[*bp])&0x80)
				return(RE_ENCODING);
			else
				length += 3;
		}
		++bp;
		j = (c1 << 2) | (c2 >> 4);
		*outbuf++=j;
		j = (c2 << 4) | (c3 >> 2);
		*outbuf++=j;
		j = (c3 << 6) | c4;
		*outbuf++=j;
		inlength -= 4;
	}

	*outlength = length;
	return(IDOK);   /* normal return */

}

/*
	Output one group of up to 3 bytes, pointed at by p, to buffer at f.
	If fewer than 3 are present, the 1 or two extras must be zeros.
*/

static void encode(f, p, count)
unsigned char *f;               /* output buffer */
unsigned char *p;               /* input buffer */
int count;                      /* count */
{
	int c1, c2, c3, c4;

	c1 = *p >> 2;
	c2 = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
	c3 = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
	c4 = p[2] & 077;
	*f++ = ENC(c1);
	*f++ = ENC(c2);
	if (count == 1)
	{
		*f++ = PAD;
		*f++ = PAD;
	}else{
		*f++ = ENC(c3);
		if(count == 2) *f++ = PAD;
		else *f++ = ENC(c4);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -