什么是使用UTF-8崩溃URLDecoder的符号?

问题描述 投票:1回答:2

我正在使用URLDecoder来解码字符串:

import java.net.URLDecoder;
URLDecoder.decode("%u6EDA%u52A8%u8F74%u627F", StandardCharsets.UTF_8.name());

这导致了崩溃

Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "u6"
    at java.net.URLDecoder.decode(URLDecoder.java:194)
    at Playground$.delayedEndpoint$Playground$1(Playground.scala:45)
    at Playground$delayedInit$body.apply(Playground.scala:10)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at Playground$.main(Playground.scala:10)
    at Playground.main(Playground.scala)

似乎%u6%u8不允许在字符串中。我试着阅读这些符号是什么,但我没有成功。我在名为“页面标题字段”的字段中的数据集中找到了该字符串。所以我怀疑它们是编码符号,我只是不知道哪种编码。有谁知道这些符号是什么以及我应该使用哪种编码来成功解码它们?

java scala url unicode decoding
2个回答
3
投票

看起来像“滚动轴承”的non-standard UTF-16-based encoding,是“滚珠轴承”的中文。

我建议用反斜杠来.replaceAll %u,然后使用Apache Commons的StringEscapeUtils

import org.apache.commons.lang3.StringEscapeUtils
val unescapedJava = StringEscapeUtils.unescapeJava(str.replaceAll("%u", "\\u"))
URLDecoder.decode(unescapedJava, StandardCharsets.UTF_8.name())

这应该处理两种类型的转义:

  • %后跟数字的正常逃逸序列不受替换和unescapeJava的影响
  • 奇怪的%u被特别处理(由\u取代),并在第一步消除。

如果(仅当)您绝对确定所有代码点都以这种方式编码,那么您可以不使用StringEscapeUtils

new String(
  "%u6EDA%u52A8%u8F74%u627F"
  .replaceAll("%u", "")
  .grouped(4)
  .map(Integer.parseInt(_, 16).toChar)
  .toArray
)

哪个产生

res: String = 滚动轴承

但是我建议反对它,因为这个方法会因为包含非转义字符的"%u6EDA%u52A8%u8F74%u627Fcafebabe"这样的输入而崩溃。更好地使用可靠的库方法来处理所有极端情况。


2
投票

你的字符串"%u6EDA%u52A8%u8F74%u627F"在语法错误中是一个URL编码的字符串。根据URLDecoder.decodeWikipedia:Percent-encoding的javadoc,每个%必须遵循两个十六进制数字。

也许你打算用"\u6EDA\u52A8\u8F74\u627F"代替。这将是一个语法正确的Java字符串(具有4个十六进制转义的Unicode字符),相当于"滚动轴承"。但是对这个字符串进行URL解码仍然没有意义。因此,我猜这个错误已经在编码方面发生了,它首先产生了这个格式错误的URL编码字符串。

© www.soinside.com 2019 - 2024. All rights reserved.