BASE64编码及SMTP协议简单实现

来源:互联网 发布:上海网络企业排名 编辑:程序博客网 时间:2024/06/12 22:58

通过这个简单的Demo程序,可以了解BASE64的编码方法和SMTP协议的报文格式,最终实现一个发送邮件的程序。


base64编解码头文件<base64.h>

#ifndef _Base64_H__#define _Base64_H__#include <stdio.h>char *base64_encode(const char *input, const size_t length,char *output);char *base64_decode(const char *input,char *output);#endif

base64编解码源文件<base64.c>

#include "base64.h"const char base64_index[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";// 16 * 16  const int base64_decode_map[256] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0   - 15  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16  - 31  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32  - 47  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48  - 63  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64  - 79  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80  - 95  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96  - 111  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112 - 127  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 - 143  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144 - 159   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160 - 175  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176 - 191  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192 - 207  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208 - 223  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224 - 239  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 240 - 255  };char *base64_encode(const char *input, const size_t length, char *output){*output = '\0';if (input == NULL || length < 1) return output;char *p = (char*)input;char *p_dst = (char*)output;;char *p_end = (char*)input + length;int  loop_count = 0;// 0x30 -> 00110000  // 0x3C -> 00111100  // 0x3F -> 00111111  while (p_end - p >= 3) {*p_dst++ = base64_index[(p[0] >> 2)];*p_dst++ = base64_index[((p[0] << 4) & 0x30) | (p[1] >> 4)];*p_dst++ = base64_index[((p[1] << 2) & 0x3C) | (p[2] >> 6)];*p_dst++ = base64_index[p[2] & 0x3F];p += 3;}if (p_end - p > 0) {*p_dst++ = base64_index[(p[0] >> 2)];if (p_end - p == 2) {*p_dst++ = base64_index[((p[0] << 4) & 0x30) | (p[1] >> 4)];*p_dst++ = base64_index[(p[1] << 2) & 0x3C];*p_dst++ = '=';}else if (p_end - p == 1) {*p_dst++ = base64_index[(p[0] << 4) & 0x30];*p_dst++ = '=';*p_dst++ = '=';}}*p_dst = '\0';return output;}char *base64_decode(const char *input, char *output){output[0] = '\0';if (input == NULL || output == NULL)return output;int input_len = strlen(input);if (input_len < 4 || input_len % 4 != 0)return output;// 0xFC -> 11111100  // 0x03 -> 00000011  // 0xF0 -> 11110000  // 0x0F -> 00001111  // 0xC0 -> 11000000  char *p = (char*)input;char *p_out = output;char *p_end = (char*)input + input_len;for (; p < p_end; p += 4) {*p_out++ = ((base64_decode_map[p[0]] << 2) & 0xFC) | ((base64_decode_map[p[1]] >> 4) & 0x03);*p_out++ = ((base64_decode_map[p[1]] << 4) & 0xF0) | ((base64_decode_map[p[2]] >> 2) & 0x0F);*p_out++ = ((base64_decode_map[p[2]] << 6) & 0xC0) | (base64_decode_map[p[3]]);}if (*(input + input_len - 2) == '=') {*(p_out - 2) = '\0';}else if (*(input + input_len - 1) == '=') {*(p_out - 1) = '\0';}return output;}

发送邮件主程序<demo.c>

#include <stdio.h>#include <stdlib.h>#include "base64.h"#include <winsock.h>#pragma comment(lib, "Ws2_32.lib")int init_socket();void socket_close();SOCKET socket_connect(const char * hostname, int port);void get_sockbuf();void send_socket(const char *data);SOCKET sockfd = 0;int main(){char data[1024] = { 0 };char base64_data[2048] = { 0 };int i = 0;init_socket();sockfd = socket_connect("smtp.qq.com", 25);//接收服务器信息get_sockbuf();//发送helo信息send_socket("helo smtp.qq.com\r\n");//接收服务器应答get_sockbuf();//发送登录请求send_socket("auth login\r\n");//接收服务器应答get_sockbuf();//发送编码后的邮箱账号memset(data, 0, sizeof(data));strcpy(data, "你自己的QQ号@qq.com");base64_encode(data, strlen(data), base64_data);i = strlen(base64_data);base64_data[i] = '\r';base64_data[i+1] = '\n';send_socket(base64_data);//接收服务器应答get_sockbuf();//发送编码后的邮箱密码memset(data, 0, sizeof(data));memset(base64_data, 0, sizeof(base64_data));strcpy(data, "你QQ邮箱的密码");base64_encode(data, strlen(data), base64_data);i = strlen(base64_data);base64_data[i] = '\r';base64_data[i + 1] = '\n';send_socket(base64_data);//接收服务器应答get_sockbuf();//mail fromsend_socket("mail from:<你自己的QQ号@qq.com>\r\n");//接收服务器应答get_sockbuf();//rcpt tosend_socket("rcpt to:<接收邮件的QQ号@qq.com>\r\n");//接收服务器应答get_sockbuf();//正文send_socket("data\r\n");send_socket("subject:test\r\n");send_socket("\r\nhello!\r\n.\r\n");//接收服务器应答get_sockbuf();//退出send_socket("quit\r\n");//接收服务器应答get_sockbuf();socket_close();system("pause");}void send_socket(const char *data){if (send(sockfd, data, strlen(data), 0) < 0){printf("发送失败!\n");return;}printf("%s", data);}void get_sockbuf(){static char buf[1024] = { 0 };memset(buf, 0, sizeof(buf));if (recv(sockfd, buf, sizeof(buf), 0) < 0){return;}printf("%s", buf);}int init_socket(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(1, 1);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return -1;}if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){WSACleanup();return -1;}return 0;}SOCKET socket_connect(const char * hostname, int port)//连接套接字{struct hostent*host;unsigned long ip = 0;if (init_socket() == -1)return 0;SOCKET st = socket(AF_INET, SOCK_STREAM, 0);if (st == 0)return 0;struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(port);ip = inet_addr(hostname);if (ip == INADDR_NONE){host = gethostbyname(hostname);addr.sin_addr = *((struct in_addr*)(host->h_addr_list[0]));}else{addr.sin_addr.s_addr = inet_addr(hostname);}if (connect(st, (struct sockaddr *)&addr, sizeof(addr)) == -1){printf("连接失败\n");return 0;}else{return st;}}void socket_close(){closesocket(sockfd);WSACleanup();}

仅仅这三个文件我们就可以实现一个小小的发送邮件的程序了。

0 0
原创粉丝点击