URL编/解码的Java语言实现
1.1、URL编码

URL编码的Java语言实现如下:

private static final String base16EncodeTable = "0123456789ABCDEF";

public static String urlEncode(byte[] data) {
    if (data == null || data.length == 0) {
        return "";
    }
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < data.length; i++) {
        byte value = data[i];
        //这些字符保持原样
        if ((value >= '0' && value < '9')
            || (value >= 'a' && value <= 'z')
            || (value >= 'A' && value <= 'Z')) {
            result.append(value);
        } else if (value == '-' || value == '_' || value == '.' || value == '*') {
            result.append(value);
        } else if (value == ' ') { //把空格编码成+
            result.append('+');
        } else { //其他字符都转换成%XY,XY是Base16编码
            //向右移动4bit,获得高4bit
            int highByte = (value >> 4) & 0x0F;
            //与0x0f做位与运算,获得低4bit
            int lowByte = value & 0x0F;
            result.append('%');
            result.append(base16EncodeTable.charAt(highByte));
            result.append(base16EncodeTable.charAt(lowByte));
        }
    }
    return result.toString();
}

此算法的结果与java.net.URLEncoder的编码结果完全一样。

1.2、URL解码

URL解码的Java语言实现如下:

//把16进制字符转换成10进制表示的数字
private static int hex2dec(char c) {
    if ('0' <= c && c <= '9') {
        return c - '0';
    } else if ('a' <= c && c <= 'f') {
        return c - 'a' + 10;
    } else if ('A' <= c && c <= 'F') {
        return c - 'A' + 10;
    } else {
        return 0;
    }
}

public static byte[] urlDecode(String input) {
    int inputLength = input.length();
    int outputLength = 0;
    byte[] output = new byte[inputLength];
    for (int i = 0; i < inputLength; i++) {
        char c = input.charAt(i);
        if (c == '%') {
            char x = input.charAt(++i);
            char y = input.charAt(++i);
            //16进制数字转换为10进制数字的过程
            output[outputLength++] = (byte) (hex2dec(x) * 16 + hex2dec(y));
        } else if (c == '+') {
            output[outputLength++] = (byte) ' ';
        } else {
            output[outputLength++] = (byte) c;
        }
    }
    byte[] outputCopy = new byte[outputLength];
    System.arraycopy(output, 0, outputCopy, 0, outputLength);
    return outputCopy;
}