1 /* Base64 library for ActionScript 3.0.
\r
2 * Based on: Ma Bingyao code.
\r
3 * Optimized by: Jean-Philippe Auclair / jpauclair.wordpress.com
\r
4 * Copyright (C) 2007 Ma Bingyao <andot@ujn.edu.cn>
\r
5 * LastModified: Oct 26, 2009
\r
6 * This library is free. You can redistribute it and/or modify it.
\r
8 package com.hurlant.util{
\r
9 import flash.utils.ByteArray;
\r
13 private static const _encodeChars : Vector.<int> = InitEncoreChar();
\r
14 private static const _decodeChars : Vector.<int> = InitDecodeChar();
\r
16 public static function encodeByteArray(data : ByteArray) : String
\r
18 var out : ByteArray = new ByteArray();
\r
19 //Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
\r
20 out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
\r
22 var r : int = data.length % 3;
\r
23 var len : int = data.length - r;
\r
24 var c : int; //read (3) character AND write (4) characters
\r
28 //Read 3 Characters (8bit * 3 = 24 bits)
\r
29 c = data[i++] << 16 | data[i++] << 8 | data[i++];
\r
31 //Cannot optimize this to read int because of the positioning overhead. (as3 bytearray seek is slow)
\r
32 //Convert to 4 Characters (6 bit * 4 = 24 bits)
\r
33 c = (_encodeChars[c >>> 18] << 24) | (_encodeChars[c >>> 12 & 0x3f] << 16) | (_encodeChars[c >>> 6 & 0x3f] << 8) | _encodeChars[c & 0x3f];
\r
35 //Optimization: On older and slower computer, do one write Int instead of 4 write byte: 1.5 to 0.71 ms
\r
38 out.writeByte(_encodeChars[c >> 18] );
\r
39 out.writeByte(_encodeChars[c >> 12 & 0x3f]);
\r
40 out.writeByte(_encodeChars[c >> 6 & 0x3f]);
\r
41 out.writeByte(_encodeChars[c & 0x3f]);
\r
45 if (r == 1) //Need two "=" padding
\r
47 //Read one char, write two chars, write padding
\r
49 c = (_encodeChars[c >>> 2] << 24) | (_encodeChars[(c & 0x03) << 4] << 16) | 61 << 8 | 61;
\r
52 else if (r == 2) //Need one "=" padding
\r
54 c = data[i++] << 8 | data[i];
\r
55 c = (_encodeChars[c >>> 10] << 24) | (_encodeChars[c >>> 4 & 0x3f] << 16) | (_encodeChars[(c & 0x0f) << 2] << 8) | 61;
\r
60 return out.readUTFBytes(out.length);
\r
64 public static function decodeToByteArray(str : String) : ByteArray
\r
72 var out : ByteArray;
\r
75 out = new ByteArray();
\r
76 var byteString : ByteArray = new ByteArray();
\r
77 byteString.writeUTFBytes(str);
\r
83 c1 = _decodeChars[byteString[i++]];
\r
84 } while (i < len && c1 == -1);
\r
85 if (c1 == -1) break;
\r
90 c2 = _decodeChars[byteString[i++]];
\r
91 } while (i < len && c2 == -1);
\r
92 if (c2 == -1) break;
\r
94 out.writeByte((c1 << 2) | ((c2 & 0x30) >> 4));
\r
99 c3 = byteString[i++];
\r
100 if (c3 == 61) return out;
\r
102 c3 = _decodeChars[c3];
\r
103 } while (i < len && c3 == -1);
\r
104 if (c3 == -1) break;
\r
106 out.writeByte(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2));
\r
110 c4 = byteString[i++];
\r
111 if (c4 == 61) return out;
\r
113 c4 = _decodeChars[c4];
\r
114 } while (i < len && c4 == -1);
\r
115 if (c4 == -1) break;
\r
117 out.writeByte(((c3 & 0x03) << 6) | c4);
\r
126 public static function encode(data : String) : String {
\r
127 // Convert string to ByteArray
\r
128 var bytes : ByteArray = new ByteArray();
\r
129 bytes.writeUTFBytes(data);
\r
131 // Return encoded ByteArray
\r
132 return encodeByteArray(bytes);
\r
135 public static function decode(data : String) : String {
\r
136 // Decode data to ByteArray
\r
137 var bytes : ByteArray = decodeToByteArray(data);
\r
139 // Convert to string and return
\r
140 return bytes.readUTFBytes(bytes.length);
\r
143 public static function InitEncoreChar() : Vector.<int>
\r
145 var encodeChars : Vector.<int> = new Vector.<int>();
\r
146 // We could push the number directly, but i think it's nice to see the characters (with no overhead on encode/decode)
\r
147 var chars : String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
\r
148 for (var i : int = 0; i < 64; i++)
\r
150 encodeChars.push(chars.charCodeAt(i));
\r
154 65, 66, 67, 68, 69, 70, 71, 72,
\r
155 73, 74, 75, 76, 77, 78, 79, 80,
\r
156 81, 82, 83, 84, 85, 86, 87, 88,
\r
157 89, 90, 97, 98, 99, 100, 101, 102,
\r
158 103, 104, 105, 106, 107, 108, 109, 110,
\r
159 111, 112, 113, 114, 115, 116, 117, 118,
\r
160 119, 120, 121, 122, 48, 49, 50, 51,
\r
161 52, 53, 54, 55, 56, 57, 43, 47);
\r
163 return encodeChars;
\r
166 public static function InitDecodeChar() : Vector.<int>
\r
168 var decodeChars : Vector.<int> = new Vector.<int>();
\r
170 decodeChars.push(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
171 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
172 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
\r
173 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
\r
174 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
\r
175 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
\r
176 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
\r
177 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
\r
178 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
179 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
180 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
181 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
182 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
183 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
184 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
\r
185 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
\r
186 return decodeChars;
\r