Java decryption for non-ASCII characters

I am trying in Java to decode a URL containing% encoded characters

I tried using the java.net.URI class to complete the task, but it does not always work correctly.

String test = "https://fr.wikipedia.org/wiki/Fondation_Alliance_fran%C3%A7aise";
URI uri = new URI(test);
System.out.println(uri.getPath());

For the test line https://fr.wikipedia.org/wiki/Fondation_Alliance_fran%C3%A7aise "the result is correct" / wiki / Fondation _Alliance_franΓ§aise "(% C3% A7 is correctly replaced by Γ§).

But for some other test strings, such as http://sv.wikipedia.org/wiki/Anv%E4ndare:Lsjbot/Statistik#Drosophilidae , it gives the wrong result "/ wiki / Anv ndare: Lsjbot / Statistik" (% E4 is replaced on instead of Γ€).

I did some testing with the getRawPath () and URLDecoder classes.

System.out.println(URLDecoder.decode(uri.getRawPath(), "UTF8"));
System.out.println(URLDecoder.decode(uri.getRawPath(), "ISO-8859-1"));
System.out.println(URLDecoder.decode(uri.getRawPath(), "WINDOWS-1252"));

:

  • % C3% A7 "UTF-8", , "ISO-8859-1" "WINDOWS-1252"
  • % E4 .

URL , Chrome.

URL- ?

==== ====

, McDowell, . :

private static void appendBytes(ByteArrayOutputStream buf, String data) throws UnsupportedEncodingException {
  byte[] b = data.getBytes("UTF8");
  buf.write(b, 0, b.length);
}

private static byte[] parseEncodedString(String segment) throws UnsupportedEncodingException {
  ByteArrayOutputStream buf = new ByteArrayOutputStream(segment.length());
  int last = 0;
  int index = 0;
  while (index < segment.length()) {
    if (segment.charAt(index) == '%') {
      appendBytes(buf, segment.substring(last, index));
      if ((index < segment.length() + 2) &&
          ("ABCDEFabcdef0123456789".indexOf(segment.charAt(index + 1)) >= 0) &&
          ("ABCDEFabcdef0123456789".indexOf(segment.charAt(index + 2)) >= 0)) {
        buf.write((byte) Integer.parseInt(segment.substring(index + 1, index + 3), 16));
        index += 3;
      } else if ((index < segment.length() + 1) &&
                 (segment.charAt(index + 1) == '%')) {
        buf.write((byte) '%');
        index += 2;
      } else {
        buf.write((byte) '%');
        index++;
      }
      last = index;
    } else {
      index++;
    }
  }
  appendBytes(buf, segment.substring(last));
  return buf.toByteArray();
}

private static String parseEncodedString(String segment, Charset... encodings) {
  if ((segment == null) || (segment.indexOf('%') < 0)) {
    return segment;
  }
  try {
    byte[] data = parseEncodedString(segment);
    for (Charset encoding : encodings) {
      try {
        if (encoding != null) {
          return encoding.newDecoder().
              onMalformedInput(CodingErrorAction.REPORT).
              decode(ByteBuffer.wrap(data)).toString();
        }
      } catch (CharacterCodingException e) {
        // Incorrect encoding, try next one
      }
    }
  } catch (UnsupportedEncodingException e) {
    // Nothing to do
  }
  return segment;
}
+3
1

Anv% E4ndare

PopoFibo , UTF-8.

:

public static String parse(String segment, Charset... encodings) {
  byte[] data = parse(segment);
  for (Charset encoding : encodings) {
    try {
      return encoding.newDecoder()
          .onMalformedInput(CodingErrorAction.REPORT)
          .decode(ByteBuffer.wrap(data))
          .toString();
    } catch (CharacterCodingException notThisCharset_ignore) {}
  }
  return segment;
}

private static byte[] parse(String segment) {
  ByteArrayOutputStream buf = new ByteArrayOutputStream();
  Matcher matcher = Pattern.compile("%([A-Fa-f0-9][A-Fa-f0-9])")
                          .matcher(segment);
  int last = 0;
  while (matcher.find()) {
    appendAscii(buf, segment.substring(last, matcher.start()));
    byte hex = (byte) Integer.parseInt(matcher.group(1), 16);
    buf.write(hex);
    last = matcher.end();
  }
  appendAscii(buf, segment.substring(last));
  return buf.toByteArray();
}

private static void appendAscii(ByteArrayOutputStream buf, String data) {
  byte[] b = data.getBytes(StandardCharsets.US_ASCII);
  buf.write(b, 0, b.length);
}

:

for (String test : Arrays.asList("Fondation_Alliance_fran%C3%A7aise",
    "Anv%E4ndare")) {
  String result = parse(test, StandardCharsets.UTF_8,
      StandardCharsets.ISO_8859_1);
  System.out.println(result);
}

, - , URL. , v% E4n - 76 E4 6E - UTF-8 .

, ( ) ISO-8859-1.


: HTTP , -, http://foo/%%%%% , URI UTF-8, . , URI, URI, .

URL- Java .

+2

All Articles