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

📄 base64.c

📁 C编写的用来实现search engine的推荐功能
💻 C
字号:
/*******************************************
 * Base64编码、解码
 * 编码中可以指明每个若干个字符插入一个换行符
 * 解码时可以忽略其中的回车、换行符
 * Author: lubing
 * Date: Oct. 26, 2000
 *******************************************/

#include <stdio.h>
#include <string.h>

#define __A      0
#define __a     26
#define __0     52
#define __plus  62
#define __slash 63

#define __stuff -2
#define __error -1

#define STUFF_CHAR '='

#ifdef WIN32
#define CRLF "\r\n"
#define CRLF_LEN 2
#else
#define CRLF "\n"
#define CRLF_LEN 1
#endif

static char* BASES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static int EncodeWithoutWrapping(const char* src, const int srclen, char* dest)
{
	int i;
	int limit = srclen - 2;
	int len = 0;
	
	//encode the src 3 chars as a group
	for (i=0; i<limit; i += 3) {
		dest[len++] = BASES[(src[i] >> 2) & 0x3f];
		dest[len++] = BASES[((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0f)];
		dest[len++] = BASES[((src[i+1] << 2) & 0x3c) | ((src[i+2] >> 6) & 0x03)];
		dest[len++] = BASES[src[i+2] & 0x3f];
	}
	
	if (i < srclen) {
		dest[len++] = BASES[(src[i] >> 2) & 0x3f];
		if (i == srclen - 1) {
			dest[len++] = BASES[((src[i] << 4) & 0x30)];
			dest[len++] = STUFF_CHAR;
		} else {
			dest[len++] = BASES[((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0f)];
			dest[len++] = BASES[((src[i+1] << 2) & 0x3c)];
		}
		dest[len++] = STUFF_CHAR;
	}
	
	dest[len] = '\0';

	return len;
}

static int EncodeWithWrapping(const char* src, const int srclen, char* dest, const int wraplen)
{
	int i;
	int limit = srclen - 2;
	int len = 0;
	int total = 0;
	
	//encode the src 3 chars as a group
	for (i=0; i<limit; i += 3) {
		dest[len++] = BASES[(src[i] >> 2) & 0x3f];
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
		dest[len++] = BASES[((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0f)];
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
		dest[len++] = BASES[((src[i+1] << 2) & 0x3c) | ((src[i+2] >> 6) & 0x03)];
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
		dest[len++] = BASES[src[i+2] & 0x3f];
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
	}
	
	if (i < srclen) {
		dest[len++] = BASES[(src[i] >> 2) & 0x3f];
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
		if (i == srclen - 1) {
			dest[len++] = BASES[(src[i] << 4) & 0x30];
			total++;
			if (total % wraplen == 0) {
				memcpy(dest+len, CRLF, CRLF_LEN);
				len += CRLF_LEN;
			}
			dest[len++] = STUFF_CHAR;
			total++;
			if (total % wraplen == 0) {
				memcpy(dest+len, CRLF, CRLF_LEN);
				len += CRLF_LEN;
			}
		} else {
			dest[len++] = BASES[((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0f)];
			total++;
			if (total % wraplen == 0) {
				memcpy(dest+len, CRLF, CRLF_LEN);
				len += CRLF_LEN;
			}
			dest[len++] = BASES[((src[i+1] << 2) & 0x3c)];
			total++;
			if (total % wraplen == 0) {
				memcpy(dest+len, CRLF, CRLF_LEN);
				len += CRLF_LEN;
			}
		}
		dest[len++] = STUFF_CHAR;
		total++;
		if (total % wraplen == 0) {
			memcpy(dest+len, CRLF, CRLF_LEN);
			len += CRLF_LEN;
		}
	}
	
	dest[len] = '\0';

	return len;
}

int Base64Encode(const char* src, const int srclen, char* dest, const int destlen, const int wraplen)
{
	int len;
	
	if (src == NULL || dest == NULL) {
		return 0;
	}
	
	len = (srclen + 2) * 4 / 3 + 1;
	if (wraplen <= 0)
	{
		if (len > destlen) {
			return 0;
		}
		
		return EncodeWithoutWrapping(src, srclen, dest);
	} else {
#ifndef WIN32
		if (len + len / wraplen > destlen) {
#else
		if (len + (len / wraplen)*2 > destlen) {
#endif
			return 0;
		}
		
		return EncodeWithWrapping(src, srclen, dest, wraplen);
	}
}

static int GetIndex(char ch)
{
	if (ch >= 'A' && ch <= 'Z') {
		return (ch - 'A' + __A);
	}
	if (ch >= 'a' && ch <= 'z') {
		return (ch - 'a' + __a);
	}
	if (ch >= '0' && ch <= '9') {
		return (ch - '0' + __0);
	}
	
	switch(ch){
	case '+':
		return __plus;

	case '/':
	case '-':
	case '%':
		return __slash;

	case STUFF_CHAR:
		return __stuff;

	default:
		return __error;
	}
}

int Base64Decode(const char* src, char* dest, const int destlen)
{
	int len;
	int base, index;
	int done = 0;

	if (src == NULL || dest == NULL) {
		return 0;
	}
	
	len = strlen(src);
	if ((len * 3 / 4) > destlen) {
		return 0;
	}
	len = 0;

	while (!done && (*src != '\0')) {
		//skip LF & CR
		if (*src == '\n' || *src == '\r') {
			src++;
			continue;
		}
		base = 0;

		//join 4 character to 24-bit

		//1st character
		switch (index = GetIndex(*src++)) {
		case __error:
			return 0;

		case __stuff:
			//'=' as the end
			done = 1;
			break;

		default:
			base |= (index << 18);
			break;
		}
		if (done) {
			//break the loop
			break;
		}

		//2nd character
		while (*src != '\0' && (*src == '\n' || *src == '\r')) {
			src++;
		}
		if (*src != '\0') {
			switch(index = GetIndex(*src++)){
			case __error:
				return 0;

			case __stuff:
				//impossible
				return 0;

			default:
				base |= (index << 12);
				break;
			}

			//3rd character
			while (*src != '\0' && (*src == '\n' || *src == '\r')) {
				src++;
			}
			if (*src != '\0') {
				switch (index = GetIndex(*src++)) {
				case __error:
					return 0;

				case __stuff:
					index = 0;
					done = 1;
				default:
					base |= (index << 6);
					break;
				}

				//4th character
				if (!done) {
					while (*src != '\0' && (*src == '\n' || *src == '\r')) {
						src++;
					}
					if (*src != '\0') {
						switch (index = GetIndex(*src ++)) {
						case __error:
							return 0;
						case __stuff:
							index = 0;
							done = 2;
						default:
							base |= index;
						}
					} else {
						done = 2;
					}
				}
			} else {
				done = 1;
			}
		} else {
			//impossible, there must be at least 2 characters
			return 0;
		}

		//decode it
		dest[len++] = (char)(base >> 16);
		if (done != 1) {
			dest[len++] = (char)(base >> 8);
			if (done != 2) {
				dest[len ++] = (char)base;
			}
		}
	}

	if (len < destlen) {
		dest[len] = 0;
	}

	return len;
}

⌨️ 快捷键说明

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