如果包含 Unicode 字符,则 PHP 中的编码字符串无法在 JavaScript 中解码



我正在尝试使用类似于 Rot13 的算法在 PHP 中编码字符串,然后在 JavaScript 中解码字符串并进行搜索和替换。它适用于ASCII字符,但不适用于Unicode。

我弄乱了附加的代码,但无法让它工作。

<?php
function strRot($str, $n) {
$len = mb_strlen($str);
$min = 0;
$max = 99999999;
$final = '';
for ($i = 0; $i < $len; $i++) {
$current = mb_ord($str[$i]);
$val = $current+$n;
if ($val >= $max) {
$val = $val - $max;
}
if ($val <= $min) {
$val = $val + $min;
}
$final .= mb_chr($val);
}
return $final;
}
?><!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<h2>Ü and 🐘. 棕色的狐狸跳了起来.</h2>
<p>The Hello, world! expression will be replaced.</p>
<p>Ü and 🐘. 棕色的狐狸跳了起来. Should be replaced too.</p>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
<script id="scriptId" type="text/javascript">
var data = [
["Hello, world!", "<?php echo base64_encode(strRot('I got replaced.', 1000)); ?>"],
["Ü and 🐘. 棕色的狐狸跳了起来.", "<?php echo base64_encode(strRot('🐘 before Ü and 棕色的.', 1000)); ?>"]
];
function b64DecodeUnicode(str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
function strRot(str, n)
{
var min = 0;
var max = 99999999;
var final = '';
for (var i in str) {
var current = str.charCodeAt(i);
var val = current+n;
if (val >= max) {
val = val - max;
}
if (val <= min) {
val = val + min;
}
final += String.fromCharCode(val);
}
return final;
}
function replace() {
for (index in data) {
//var regex = new RegExp(data[index][0], "ug");
jQuery("html *:not(script[id=scriptId])").children().each(function () {
jQuery(this).html(jQuery(this).html().replace(
data[index][0],
strRot(b64DecodeUnicode(data[index][1]), -1000)
));
});
}
}
replace();
</script>
</body>
</html>

一旦JS运行,它就会用解码的数据[索引][1]替换数据[索引][0]。

(我没有足够的声誉来评论,所以我求助于使用答案......

不确定它是否有区别,但在 HTML "h2"标头中,您的 Unicode 表达式是......

Ü an 🐘. 棕色的狐狸跳了起来.

。在数据[]中,它是...

Ü and 🐘. 棕色的狐狸跳了起来.

假设"an"和"and"应该是相同的?

我找到的一个解决方案:

var data = [
["Hello, world!", "<?php echo base64_encode(strRot(rawurlencode('I got replaced.'), 1000)); ?>"],
["Ü and 🐘. 棕色的狐狸跳了起来.", "<?php echo base64_encode(strRot(rawurlencode('🐘 before Ü and 棕色的.'), 1000)); ?>"]
];
// Then, in replace():
decodeURIComponent(strRot(b64DecodeUnicode(data[index][1]), -1000))

这是有效的,因为它在旋转之前转义了所有 unicode 字符。 唯一的问题是,由于转义,当涉及到字符串的大小时,它会增加一些开销。

相关内容

  • 没有找到相关文章

最新更新