#include #include #include #include #include #include #include #include #include #include #include "tango_cache_tools.h" static const char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) #define B64_EOLN 0xF0 #define B64_CR 0xF1 #define B64_EOF 0xF2 #define B64_WS 0xE0 #define B64_ERROR 0xFF #define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) #define B64_BASE64(a) !B64_NOT_BASE64(a) static const unsigned char data_ascii2bin[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; //切记不可以如此调用: conv_ascii2bin(x++); 因为会++两次 #define conv_ascii2bin(aa) (((aa) & 0x80)?(0xFF):data_ascii2bin[(aa)]) /********************************************************************* 函数名称:Base64_EncodeBlock 功能简介:对一完整BASE64编码块进行编码 输入参数:in:待编码的字符; inl:in的长度 输出参数:out:编码后存储的缓冲区; 返回值:编码后的长度 *********************************************************************/ int Base64_EncodeBlock(const unsigned char *in, int inl, unsigned char *out) { int i, ret = 0; unsigned long l; for (i = inl; i > 0; i -= 3) { if (i >= 3) { l = (((unsigned long)in[0]) << 16L) | (((unsigned long)in[1]) << 8L) | in[2]; *(out++) = conv_bin2ascii(l >> 18L); *(out++) = conv_bin2ascii(l >> 12L); *(out++) = conv_bin2ascii(l >> 6L); *(out++) = conv_bin2ascii(l); } else { l = ((unsigned long)in[0]) << 16L; if (i == 2) l |= ((unsigned long)in[1] << 8L); *(out++) = conv_bin2ascii(l >> 18L); *(out++) = conv_bin2ascii(l >> 12L); *(out++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); *(out++) = '='; } ret += 4; in += 3; } *out = '\0'; return (ret); } /********************************************************************* 函数名称:Base64_DecodeBlock 功能简介:对一完整BASE64编码块进行解析,自动忽略首尾非BASE64编码字符 输入参数:in:待解码的字符; inl:in的长度 输出参数:out:解码后存储的缓冲区; 必须保证有足够的空间,一般达到@inl大小即可; 返回值:<0:失败;>=0:解码后的长度 *********************************************************************/ int Base64_DecodeBlock(const unsigned char *in, int inl, unsigned char *out, int outsize) { int i, ret = 0; unsigned char a, b, c, d; unsigned long l; /* ignore not-base64-encoded charactor. */ while ((conv_ascii2bin(*in) == B64_WS) && (inl > 0)) { in++; inl--; } while ((inl > 3) && (B64_NOT_BASE64(conv_ascii2bin(in[inl - 1])))) inl--; if (inl % 4 != 0) return -1; if(outsize < (inl*3)/4) return -2; for (i = 0; i < inl; i += 4) { a = conv_ascii2bin(*(in)); b = conv_ascii2bin(*(in+1)); c = conv_ascii2bin(*(in+2)); d = conv_ascii2bin(*(in+3)); if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) return (-1); l = ((((unsigned long)a) << 18L) | (((unsigned long)b) << 12L) | (((unsigned long)c) << 6L) | (((unsigned long)d))); *(out++) = (unsigned char)(l >> 16L) & 0xff; *(out++) = (unsigned char)(l >> 8L) & 0xff; *(out++) = (unsigned char)(l) & 0xff; ret += 3; in+=4; } for(i = inl; i > 0; i -= 4) { if(*(in-3) == '=') { in -= 4; ret -= 3; continue; } while(*(--in) == '=') ret -= 1; break; } return ret; } //已知两个串长度相同的情况下,比较两个串是否相等 int strcmp_one_word_mesa_equal_len(const char *s1_lowercase, const char *s1_uppercase, const char *s2, size_t len) { unsigned char *s1,*s12; if (s2[len-1]-'a'>=0) { s1 = (unsigned char *)s1_lowercase; s12= (unsigned char *)s1_uppercase; } else { s1 = (unsigned char *)s1_uppercase; s12= (unsigned char *)s1_lowercase; } do { if (*s1 == *s2 || *s12 == *s2) { ++s1; ++s12; ++s2; continue; } return 0; } while (--len); return 1; } int mkdir_according_path(const char * path) { char buffer[256]; const char *ps=path, *pc; if(*ps == '/') ps += 1; while((pc = strchr(ps, '/')) != NULL) { while(*(pc+1) == '/') pc++; memcpy(buffer, path, pc - path); buffer[pc-path] = '\0'; if(access(buffer, F_OK)) { if(mkdir(buffer, 0777) && errno!=EEXIST) { return -1; } } ps = pc + 1; } if(access(path, F_OK)) { if(mkdir(path, 0777)) { return -1; } } return 0; } //将时间字符串转换为时间戳 time_t expires_hdr2timestamp(const char *expires_val, int len) { struct tm tm; time_t expire; while(len > 0 && (*expires_val==' '||*expires_val=='\t'||*expires_val=='\r'||*expires_val=='\n')) { expires_val++; len--; } if(len == 0) { return 0; } if(strptime(expires_val, "%a, %d %b %Y %T", &tm) == NULL) { return 0; } expire = mktime(&tm); return expire; } //将本地时间戳转换为GMT时间字符串 size_t expires_timestamp2hdr_str(time_t seconds, char *buffer, size_t size) { struct tm save; return strftime(buffer, size, "Expires: %a, %d %b %Y %T GMT", gmtime_r(&seconds, &save)); } //将本地时间戳转换为GMT时间戳 time_t get_gmtime_timestamp(time_t seconds) { struct tm *tm, save; tm = gmtime_r(&seconds, &save); return mktime(tm); }