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

📄 mime.cs

📁 A project written in C# sends email without smtp server. It queries dns server for mx records and se
💻 CS
字号:
// $Id: MIME.cs,v 1.3 2006/08/07 08:15:36 ethem Exp $
namespace Erle
{
	using System;
	using System.IO;
	using System.Text;

	[Flags]
	public enum SmtpEncode : byte
	{
		None = 0x00,
		Dot = 0x01,
		TrailingSoft = 0x02,
		All = 0xff
	}

	public sealed class MIME
	{
		private MIME() { }
		private static readonly byte[] crlf = Encoding.ASCII.GetBytes("\r\n");
		private static readonly byte[] eq_crlf = Encoding.ASCII.GetBytes("=\r\n");
		private static readonly byte[] eq_crlf_crlf = Encoding.ASCII.GetBytes("=\r\n\r\n");
		private static readonly char[] hexChars =
		{
			'0', '1', '2', '3', '4', '5', '6', '7',	'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
		};
		private static readonly byte[] hex =
		{
			(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
			(byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F'
		};

		#region encodemap
		private const byte NUL = 0x00;	// don't encode
		private const byte ESC = 0x01;	// always encode
		private const byte SPC = 0x02;	// horizontal whitespace
		private const byte BOL = 0x03;	// encode if at beginning of line
		private const byte CR = 0x04;	// carriage return
		private const byte LF = 0x05;	// linefeed
		private static readonly byte[] encodemap =
		{
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   000-007
			ESC, SPC,  LF, ESC, ESC,  CR, ESC, ESC,      //   010-017
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   020-027
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   030-037
			SPC, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   040-047   !"#$%&'
			NUL, NUL, NUL, NUL, NUL, NUL, BOL, NUL,      //   050-057  ()*+,-./
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   060-067  01234567
			NUL, NUL, NUL, NUL, NUL, ESC, NUL, NUL,      //   070-077  89:;<=>?

			NUL, NUL, NUL, NUL, NUL, NUL, BOL, NUL,      //   100-107  @ABCDEFG
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   110-117  HIJKLMNO
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   120-127  PQRSTUVW
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   130-137  XYZ[\]^_
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   140-147  `abcdefg
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   150-157  hijklmno
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,      //   160-167  pqrstuvw
			NUL, NUL, NUL, NUL, NUL, NUL, NUL, ESC,      //   170-177  xyz{|}~

			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   200-207
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   210-217
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   220-227
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   230-237
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   240-247
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   250-257
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   260-267
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   270-277

			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   300-307
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   310-317
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   320-327
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   330-337
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   340-347
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   350-357
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   360-367
			ESC, ESC, ESC, ESC, ESC, ESC, ESC, ESC,      //   370-377
		};
		#endregion

		#region decodemap
		private const byte DNUL = 0x7F;
		private const byte DESC = 0x7E;
		private const byte DCR = 0x7D;
		private const byte DLF = 0x7C;
		private static readonly byte[] decodemap =
		{
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   000-007
			DNUL, DNUL,  DLF, DNUL, DNUL,  DCR, DNUL, DNUL,      //   010-017
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   020-027
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   030-037
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   040-047   !"#$%&'
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   050-057  ()*+,-./
			   0,	 1,	   2,	 3,	   4,	 5,	   6,	 7,		 //   060-067  01234567
			   8,    9, DNUL, DNUL, DNUL, DESC, DNUL, DNUL,		 //   070-077  89:;<=>?

			DNUL,  10,  11,  12,  13,  14,  15, DNUL,			 //   100-107  @ABCDEFG
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   110-117  HIJKLMNO
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   120-127  PQRSTUVW
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   130-137  XYZ[\]^_
			DNUL,  10,  11,  12,  13,  14,  15, DNUL,			 //   140-147  `abcdefg
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   150-157  hijklmno
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   160-167  pqrstuvw
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   170-177  xyz{|}~

			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   200-207
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   210-217
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   220-227
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   230-237
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   240-247
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   250-257
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   260-267
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   270-277

			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   300-307
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   310-317
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   320-327
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   330-337
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   340-347
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   350-357
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   360-367
			DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL, DNUL,      //   370-377
		};
		#endregion

		#region QPEncode
		public static byte[] QPEncode(byte[] originalBuffer)
		{
			return QPEncode(originalBuffer, SmtpEncode.All);
		}

		public static byte[] QPEncode(byte[] originalBuffer, SmtpEncode flags)
		{
			if (originalBuffer == null)
				return null;

			byte lastByte = NUL;
			bool hadWhitespace = false;
			int column = 0, buflen = originalBuffer.Length;
			MemoryStream ms = new MemoryStream();
			try
			{
				for (int i = 0; i < buflen; i++)
				{
					byte b = originalBuffer[i];
					byte c = encodemap[b];
					switch (c)
					{
						case NUL:
							ms.WriteByte(b);
							column++;
							hadWhitespace = false;
							break;

						case SPC:
							ms.WriteByte(b);
							column++;
							hadWhitespace = true;
							break;

						default:
							if (c != LF || lastByte != CR)
							{
								switch (c)
								{
									case CR:
									case LF:
										if (hadWhitespace)
										{
											ms.Write(eq_crlf_crlf, 0, eq_crlf_crlf.Length);
											hadWhitespace = false;
										}
										else
										{
											ms.Write(crlf, 0, crlf.Length);
										}
										column ^= column;
										break;

									default:
										if ((c == BOL) && (column != 0) && ((flags & SmtpEncode.Dot) != SmtpEncode.None))
										{
											ms.WriteByte(b);
											column++;
											hadWhitespace = false;
										}
										else
										{
											ms.Write(new byte[] { (byte)'=', hex[0x0f & (b >> 4)], hex[0x0f & b] }, 0, 3);
											column += 3;
											hadWhitespace = false;
										}
										break;
								}
							}
							break;
					}
					lastByte = c;
					// ASSERT: Debug.Assert(column <= 76);
					if (column >= 73)
					{
						ms.Write(eq_crlf, 0, eq_crlf.Length);
						column ^= column;
						hadWhitespace = false;
					}
				}

				// need eof?
				if (((flags & SmtpEncode.TrailingSoft) != SmtpEncode.None) && (column != 0))
					ms.Write(eq_crlf, 0, eq_crlf.Length);

				byte[] ret = ms.ToArray();
				return ret;
			}
			catch
			{
				return null;
			}
			finally
			{
				ms.SetLength(0L);
				ms.Capacity = 0;
				ms.Close();
				ms = null;
			}
		}
		#endregion

		#region QPDecode
		public static byte[] QPDecode(byte[] decodedBuffer)
		{
			byte[] ret = null;
			if (decodedBuffer != null)
			{
				int buflen = decodedBuffer.Length;
				MemoryStream ms = new MemoryStream();
				byte[] token = new byte[3];
				int tokenLength = 0, i = 0;
				try
				{
					while (i < buflen)
					{
						if (tokenLength == 0)
						{
							int j = i;
							while (i < buflen && decodemap[decodedBuffer[i]] != DESC)
								i++;
							if (i != j)
								ms.Write(decodedBuffer, j, i - j);
							if (i >= buflen)
								break;
						}

						byte b = decodedBuffer[i++];
						byte c = decodemap[b];

						token[tokenLength++] = b;

						if (tokenLength == 3)
						{
							tokenLength ^= tokenLength;
							// assert (decodemap[token[0]] == DESC)
							byte n1 = decodemap[token[1]];
							byte n2 = decodemap[token[2]];
							if (n1 == DCR || n1 == DLF)
							{  // "=\r", "=\n", or "=\r\n"
								if (n1 == DLF || n2 != DLF)
								{
									if (n2 == DESC)
									{
										token[0] = token[2];
										tokenLength = 1;
									}
									else
									{
										ms.WriteByte(token[2]);
									}
								}
							}
							else
							{
								if (n1 <= 15 || n2 <= 15)
								{
									ms.WriteByte((byte)((n1 << 4) | n2));
									continue;
								}
								ms.Write(token, 0, token.Length);
							}
						}
					}
					ret = ms.ToArray();
				}
				catch
				{
					ret = null;
				}
				finally
				{
					ms.SetLength(0L);
					ms.Capacity = 0;
					ms.Close();
					ms = null;
				}
			}
			return ret;

		}
		#endregion

		#region QEncode
		internal static String QEncode(byte[] bufferOriginal, string charSet)
		{
			if (bufferOriginal == null) return String.Empty;
			int bufferLen = bufferOriginal.Length;
			if (bufferLen == 0) return String.Empty;
			if (charSet == null || charSet == string.Empty)
				charSet = Erle.DnsMail.MailInfo.DefaultCharset;
			try
			{
				int nRead = 0; StringBuilder sb = new StringBuilder();
				sb.Append("=?" + charSet + "?Q?");
				char ch;
				while (nRead < bufferLen)
				{
					ch = (char)bufferOriginal[nRead++];
					if (((ch > 32 && ch < 61) || (ch > 61 && ch < 127)) && ch != '?' && ch != '_')
					{
						sb.Append(ch);
						continue;
					}
					sb.Append('=');
					sb.Append(hexChars[(ch >> 4) & 0x0f]);
					sb.Append(hexChars[ch & 0x0f]);
				}
				sb.Append("?=");
				return sb.ToString();
			}
			catch
			{
				return String.Empty;
			}
			finally
			{
				bufferOriginal = null;
			}
		}
		#endregion

		#region BEncode
		internal static String BEncode(byte[] bufferOriginal, string charSet)
		{
			if (bufferOriginal == null) return String.Empty;
			int bufferLen = bufferOriginal.Length;
			if (bufferLen == 0) return String.Empty;
			if (charSet == null || charSet == string.Empty)
				charSet = Erle.DnsMail.MailInfo.DefaultCharset;
			try
			{
				StringBuilder sb = new StringBuilder();
				sb.Append("=?" + charSet + "?B?");
				sb.Append(Convert.ToBase64String(bufferOriginal));
				sb.Append("?=");
				return sb.ToString();
			}
			catch
			{
				return String.Empty;
			}
			finally
			{
				bufferOriginal = null;
			}
		}
		#endregion
	}
};

⌨️ 快捷键说明

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