unit uQuotePrintable;
(************************************************)
(* *)
(* 作者: Fengsh *)
(* @Copy Right for fsh *)
(* QQ:19985430 *)
(* *)
(************************************************)
(*
ASCII 码对照表
二制制 八进制 十六进制 十进制 字符 二制制 八进制 十六进制 十进制 字符
0000 0000 00 00 0 nul 0100 0000 100 40 64 @
0000 0001 01 01 1 soh 0100 0001 101 41 65 A
0000 0010 02 02 2 stx 0100 0010 102 42 66 B
0000 0011 03 03 3 etx 0100 0011 103 43 67 C
0000 0100 04 04 4 eot 0100 0100 104 44 68 D
0000 0101 05 05 5 enq 0100 0101 105 45 69 E
0000 0110 06 06 6 ack 0100 0110 106 46 70 F
0000 0111 07 07 7 bel 0100 0111 107 47 71 G
0000 1000 10 08 8 bs 0100 1000 110 48 72 H
0000 1001 11 09 9 ht 0100 1001 111 49 73 I
0000 1010 12 0a 10 nl 0100 1010 112 4a 74 J
0000 1011 13 0b 11 vt 0100 1011 113 4b 75 K
0000 1100 14 0c 12 ff 0100 1100 114 4c 76 L
0000 1101 15 0d 13 er 0100 1101 115 4d 77 M
0000 1110 16 0e 14 so 0100 1110 116 4e 78 N
0000 1111 17 0f 15 si 0100 1111 117 4f 79 O
0001 0000 20 10 16 dle 0101 0000 120 50 80 P
0001 0001 21 11 17 dc1 0101 0001 121 51 81 Q
0001 0010 22 12 18 dc2 0101 0010 122 52 82 R
0001 0011 23 13 19 dc3 0101 0011 123 53 83 S
0001 0100 24 14 20 dc4 0101 0100 124 54 84 T
0001 0101 25 15 21 nak 0101 0101 125 55 85 U
0001 0110 26 16 22 syn 0101 0110 126 56 86 V
0001 0111 27 17 23 etb 0101 0111 127 57 87 W
0001 1000 30 18 24 can 0101 1000 130 58 88 X
0001 1001 31 19 25 em 0101 1001 131 59 89 Y
0001 1010 32 1a 26 sub 0101 1010 132 5a 90 Z
0001 1011 33 1b 27 esc 0101 1011 133 5b 91 [
0001 1100 34 1c 28 fs 0101 1100 134 5c 92 \
0001 1101 35 1d 29 gs 0101 1101 135 5d 93 ]
0001 1110 36 1e 30 re 0101 1110 136 5e 94 ^
0001 1111 37 1f 31 us 0101 1111 137 5f 95 _
0010 0000 40 20 32 sp 0110 0000 140 60 96 '
0010 0001 41 21 33 ! 0110 0001 141 61 97 a
0010 0010 42 22 34 " 0110 0010 142 62 98 b
0010 0011 43 23 35 # 0110 0011 143 63 99 c
0010 0100 44 24 36 $ 0110 0100 144 64 100 d
0010 0101 45 25 37 % 0110 0101 145 65 101 e
0010 0110 46 26 38 & 0110 0110 146 66 102 f
0010 0111 47 27 39 ` 0110 0111 147 67 103 g
0010 1000 50 28 40 ( 0110 1000 150 68 104 h
0010 1001 51 29 41 ) 0110 1001 151 69 105 i
0010 1010 52 2a 42 * 0110 1010 152 6a 106 j
0010 1011 53 2b 43 + 0110 1011 153 6b 107 k
0010 1100 54 2c 44 , 0110 1100 154 6c 108 l
0010 1101 55 2d 45 - 0110 1101 155 6d 109 m
0010 1110 56 2e 46 . 0110 1110 156 6e 110 n
0010 1111 57 2f 47 / 0110 1111 157 6f 111 o
0011 0000 60 30 48 0 0111 0000 160 70 112 p
0011 0001 61 31 49 1 0111 0001 161 71 113 q
0011 0010 62 32 50 2 0111 0010 162 72 114 r
0011 0011 63 33 51 3 0111 0011 163 73 115 s
0011 0100 64 34 52 4 0111 0100 164 74 116 t
0011 0101 65 35 53 5 0111 0101 165 75 117 u
0011 0110 66 36 54 6 0111 0110 166 76 118 v
0011 0111 67 37 55 7 0111 0111 167 77 119 w
0011 1000 70 38 56 8 0111 1000 170 78 120 x
0011 1001 71 39 57 9 0111 1001 171 79 121 y
0011 1010 72 3a 58 : 0111 1010 172 7a 122 z
0011 1011 73 3b 59 ; 0111 1011 173 7b 123 {
0011 1100 74 3c 60 < 0111 1100 174 7c 124 |
0011 1101 75 3d 61 = 0111 1101 175 7d 125 }
0011 1110 76 3e 62 > 0111 1110 176 7e 126 ~
0011 1111 77 3f 63 ? 0111 1111 177 7f 127 del
*)
{
Char = 1字节 = 8bit = 2^8 = 256 ASCII码正好为8bit 从0~255个值。
一个汉字 = 2 字节 = 2 * 8bit = 2^16
Email中
QP使用"="开头的转义字符. 一般限制行宽为76
QP编码原理:
任何8-bit字节值可编码为3个字符: 一个等号"="后跟随两个十六进制数字
(0–9或A–F)表示该字节的数值。
等号"="(十进制值为61)不可以这样直接表示。
标准ASCII码中除了十进制33-60,62-126范围的字符不需要转换外,其它ASCII码值都
需要转为"=XX"的形式,其中XX为两个十六进制的值(大写)。为保证输出行不超过规
定长度,可在行尾加“=/r/n”序列作为软回车。
注:
ASCII的水平制表符(tab)与空格符, 十进制为9和32, 如果不出现在行尾则可以
用其ASCII字符编码直接表示。如果这两个字符出现在行尾,必须QP编码表示为
"=09" (tab)或"=20" (space).
如果数据中包含有意义的行结束标志,必须转换为ASCII回车(CR)换行(LF)序列
,既不能用原来的ASCII字符也不能用QP编码的"="转义字符序列。 相反,如果
字节值13与10有其它的不是行结束的含义,它们必须QP编码为=0D与=0A.
quoted-printable编码的数据的每行长度不能超过76个字符. 为满足此要求又
不改变被编码文本,在QP编码结果的每行末尾加上软换行(soft line break).
即在每行末尾加上一个"=", 但并不会出现在解码得到的文本中.
QP解码:
碰到=号,并且后面1位字符和2位字符分别在0-9 ,A-F中时要将字符转为十六进制,
然后求出该十六进制对应的十进制值,然后将得到的十进制值分转为对应的ASCII
字符值。
}
interface
uses
Sysutils,Classes,uBinTrans;
{ Quoted-Printable 解码 }
function DecodeQuotedPrintable(Const EncodeString:String):String;
{ Quoted-Printable 编码 }
function EncodeQuotedPrintable(Const Src:String;Const LineLen:Integer=76):String;
implementation
//for Mine QP Very Good
function EncodeQuotedPrintable(Const Src:String;Const LineLen:Integer):String;
Const
SoftCRLF = '='; //QP编码后的软回车 非真实字符串的回车是为了MIME中长度限制为76而设
CRLF = #13#10;
var
Loop:Integer;
sLen:Integer;
encodeLen:Integer;
RetStr:String;
CurrentChar:Char;
Rows:Integer;
tLen:Integer;
begin
sLen := Length(Src);
RetStr := Emptystr;
Rows := 1;
for Loop := 1 to sLen do
begin
//取当前字符
CurrentChar := Src[Loop];
encodeLen := Length(RetStr);
tLen := Rows*LineLen;
if tLen - encodeLen = 0 then
begin
RetStr := RetStr + CRLF;
Inc(Rows);
end;
if (encodeLen < tLen) and (tLen - encodeLen < 3) then
begin
RetStr := RetStr + SoftCRLF + CRLF;
Inc(Rows);
end;
if sLen-Loop>=2 then
begin
//碰到tab 和 space符 并且在行尾的要进行转码 =09(tab) =20(space)
if (CurrentChar in [#9,#32]) and (Src[Loop+1] = #13) and (Src[Loop+2] = #10) then
begin
RetStr := RetStr + '=' + IntToHex(ord(CurrentChar),2);
Continue;
end;
end;
//最后一个字符是tab 和space时也是要转的
if sLen = Loop then
begin
if CurrentChar in [#9,#32] then
begin
RetStr := RetStr + '=' + IntToHex(ord(CurrentChar),2);
Continue;
end;
end;
//不在33-60, 62-126的进行转码
if CurrentChar in [#0..#8,#10..#31,#61,#127..#255] then
RetStr := RetStr + '=' + IntToHex(ord(CurrentChar),2)
else
RetStr := RetStr + CurrentChar;
end;
Result := RetStr;
end;
//for Mime very good
function DecodeQuotedPrintable(Const EncodeString:String):String;
var
Loop:Integer;
sLen:Integer;
RetStr:String;
cChar : Char;
begin
RetStr := EmptyStr;
sLen := Length(EncodeString);
Loop := 1;
while Loop <= sLen do
begin
cChar := EncodeString[Loop];
if (cChar = #13) or (cChar=#10) then
begin
Inc(Loop);
Continue;
end;
//判断=号是否在行尾
if sLen-Loop>=2 then
begin
//如果是软回车,把'='号掉弃
if (cChar = #61) and (EncodeString[Loop+1]=#13) and (EncodeString[Loop+2]=#10) then
begin
Inc(Loop);
Continue;
end;
//如果=后跟两个十六进制字符,则要斩为相应十进制的ASCII码
if (cChar = #61)
and (EncodeString[Loop+1] in ['0'..'9', 'A'..'F'])
and (EncodeString[Loop+2] in ['0'..'9', 'A'..'F']) then
begin
RetStr := RetStr + Char(HexToInt(EncodeString[Loop+1] + EncodeString[Loop+2]));
Inc(Loop,3);
Continue;
end
else
RetStr := RetStr + cChar;
end
else
RetStr := RetStr + cChar;
Inc(Loop);
end;
Result := RetStr;
end;
end.
QuotePrintable编码原理
最新推荐文章于 2023-08-13 19:46:24 发布