public static byte[] decode(String raw) throws IllegalArgumentException {
		int length = 0;
		if (raw == null || (length = raw.length()) == 0 || length % 4 != 0) {
			throw new IllegalArgumentException(
					"input should not be null and should be mod 4");
		}

		byte[] buffer = null;
		if (raw.charAt(length - 1) == '=') {
			if (raw.charAt(length - 2) == '=') {
				buffer = new byte[length / 4 * 3 - 2];
			} else {
				buffer = new byte[length / 4 * 3 - 1];
			}
		} else {
			buffer = new byte[length / 4 * 3];
		}

		int tracker = 0;
		byte b1 = 0;
		byte b2 = 0;
		byte b3 = 0;
		byte b4 = 0;
		int i = 0;
		while (i + 3 <= buffer.length) {
			b1 = translate(raw.charAt(tracker));
			b2 = translate(raw.charAt(tracker + 1));
			b3 = translate(raw.charAt(tracker + 2));
			b4 = translate(raw.charAt(tracker + 3));

			buffer[i++] = (byte) ((b1 << 2) | ((b2 >> 4) & 0x3));
			buffer[i++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
			buffer[i++] = (byte) (((b3 & 0x3) << 6) | b4);
			tracker += 4;
		}

		switch (buffer.length - i) {
		case 0:
			break;
		case 1:
			b1 = translate(raw.charAt(tracker));
			b2 = translate(raw.charAt(tracker + 1));
			buffer[i++] = (byte) ((b1 << 2) | ((b2 >> 4) & 0x3));
			break;
		case 2:
			b1 = translate(raw.charAt(tracker));
			b2 = translate(raw.charAt(tracker + 1));
			buffer[i++] = (byte) ((b1 << 2) | ((b2 >> 4) & 0x3));
			b3 = translate(raw.charAt(tracker + 2));
			buffer[i] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
			break;
		default:
			throw new IllegalArgumentException(
					"unexpected base64 enconde,should not here");
		}
		return buffer;
	}