String (String s) { if (s.indexOf('%') == -1) { return s; } StringBuilder decoded = new StringBuilder(); final int len = s.length(); int i = 0; while (i < len) { char c = s.charAt(i); if (c == '%') { List<Integer> bytes = new ArrayList<>(); while (i + 2 < len && s.charAt(i) == '%') { final int d1 = decode(s.charAt(i + 1)); final int d2 = decode(s.charAt(i + 2)); if (d1 != -1 && d2 != -1) { bytes.add(((d1 & 0xf) << 4 | d2 & 0xf)); i += 3; } else { break; } } if (!bytes.isEmpty()) { final byte[] bytesArray = new byte[bytes.size()]; for (int j = 0; j < bytes.size(); j++) { bytesArray[j] = (byte)bytes.get(j).intValue(); } decoded.append(new String(bytesArray, StandardCharsets.UTF_8)); continue; } } decoded.append(c); i++; } return decoded.toString(); }