str_rot13

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

str_rot13对字符串执行 rot13 变换

说明

str_rot13(string $string): string

string 参数执行 ROT13 编码,并返回结果字符串。

ROT13 编码只是将每个字母在字母表中移动 13 个位置,而保持非字母字符不变。编码和解码由同一个函数完成,将编码后的字符串作为参数传递将返回原始版本。

参数

string

输入字符串。

返回值

返回给定字符串的 ROT13 版本。

示例

示例 #1 str_rot13() 示例

<?php

echo str_rot13('PHP 4.3.0'); // CUC 4.3.0

?>

添加备注

用户贡献笔记 12 notes

42
shaun
12 年前
我再次被提醒需要一个通用的 str_rot 函数。与它们的 C 对应部分相比,PHP 中的字符操作循环很慢,因此这里有一个经过调整的先前函数版本。它快 1.6 倍,主要是通过避免 chr() 调用。

<?php
function str_rot($s, $n = 13) {
static
$letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$n = (int)$n % 26;
if (!
$n) return $s;
if (
$n == 13) return str_rot13($s);
for (
$i = 0, $l = strlen($s); $i < $l; $i++) {
$c = $s[$i];
if (
$c >= 'a' && $c <= 'z') {
$s[$i] = $letters[(ord($c) - 71 + $n) % 26];
} else if (
$c >= 'A' && $c <= 'Z') {
$s[$i] = $letters[(ord($c) - 39 + $n) % 26 + 26];
}
}
return
$s;
}
?>

但是使用 strtr() 可以获得比以上快 10 倍的东西

<?php
function str_rot($s, $n = 13) {
static
$letters = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz';
$n = (int)$n % 26;
if (!
$n) return $s;
if (
$n < 0) $n += 26;
if (
$n == 13) return str_rot13($s);
$rep = substr($letters, $n * 2) . substr($letters, 0, $n * 2);
return
strtr($s, $letters, $rep);
}
?>

这种技术更快,因为 PHP 的 strtr 使用字节查找表在 C 中实现(它具有 O(m + n) 复杂度)。但是,PHP 6 将使用 Unicode,所以我猜(?) strtr 随后必须为每个字符执行搜索(O(m * n))。使用 strtr 仍然可能更快,因为它将字符操作卸载到 C 而不是 PHP,但我并不真正了解。随便选吧。

编码愉快!

(基准代码)

<?php
for ($k = 0; $k < 10; $k++) {
$s = 'The quick brown fox jumps over the lazy dog.';
$t = microtime(1);
for (
$i = 0; $i < 1000; $i++) $s = str_rot($s, $i);
$t = microtime(1) - $t;
echo
number_format($t, 3) . "\n";
}
?>
3
peter at NOSPAM jamit dot com
14 年前
此 ROT13 变体与我之前版本的不同之处在于它保留了“民族性”。例如,一段中文文本在加密后将保持中文,字符串将没有意义(真正的含义将被加密)。只要看一下代码,你就会明白。

<?php

function unichar2ords($char, $encoding = 'UTF-8') {
$char = mb_convert_encoding($char, 'UCS-4', $encoding);
$val = unpack('N', $char);
return
$val[1];
}

function
ords2unichar($ords, $encoding = 'UTF-8'){
$char = pack('N', $ords);
return
mb_convert_encoding($char, $encoding, 'UCS-4');
}

function
mbStringToArray ($string, $encoding = 'UTF-8') {
if (empty(
$string)) return false;
for (
$strlen = mb_strlen($string, $encoding); $strlen > 0; ) {
$array[] = mb_substr($string, 0, 1, $encoding);
$string = mb_substr($string, 1, $strlen, $encoding);
$strlen = $strlen - 1;
}
return
$array;
}

function
unicodeRotN($str, $offset, $encoding = 'UTF-8') {
$val = '';
$array = mbStringToArray ($str, $encoding = 'UTF-8');
$len = count($array);
for (
$i = 0; $i < $len; $i++) {
$val .= ords2unichar(unichar2ords($array[$i], $encoding) + $offset, $encoding);
}
return
$val;
}

// example

$original = '中國是我的家'; // means "China is my home"

$encrypted = unicodeRotN($string, 13); // 为團昼戞皑寃 means "Ñ Ai injustice for the Mission Day" (Google translation)

$decrypted = unicodeRotN($encrypted, -13); // 中國是我的家

?>
1
arthur at kuhrmeier dot com
9 年前
我正在为我的网站编写一个函数来旋转数字,并不断扩展它。我添加了额外的字符,定义百分比的偏移的能力,以及要影响的字符类型。

<?php
//================================================== 字符串旋转扩展
function str_shift ($string, $perc=50, $useextra=FALSE, $usedigits=TRUE, $useupper=TRUE, $uselower=TRUE) {
static
$chars = array(
'lower' => 'abcdefghijklmnopqrstuvwxyz',
'upper' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'digits' => '0123456789',
'extra' => ',.-()<>%/!"&=;:_[]{}#\\?\'+*',
);
settype($perc, 'float');
if (!
$perc) return $string;
$perc = fmod((abs($perc) < 1 ? 100*$perc : $perc), 100);
if (
$perc < 0) $perc += 100;
$use = (is_array($useextra) ? $useextra : array('lower'=>$uselower, 'upper'=>$useupper, 'digits'=>$usedigits, 'extra'=>$useextra));
foreach (
$chars as $type => $letters) {
if (!
$use[$type]) continue;
$shift = round(strlen($letters) * $perc / 100);
$repl = substr($letters, $shift).substr($letters, 0, $shift);
$string = strtr($string, $letters, $repl);
}
return
$string;
}

//===== 用法 =====

string str_shift ( string $str [, float $percent [, bool $useextra [, bool $usedigits [, bool $uselower [, bool $useupper] ] ] ] ] )

string str_shift ( string $str [, float $percent [, array $usetypes ] ] )

$usetypes = array('lower'=>bool $uselower, 'upper'=>bool $useupper, 'digits'=>bool $usedigits, 'extra'=>bool $useextra);

//===== 示例 =====

$string = "Peter's 17 pets (incl. 5 hamsters) love Dr Sarah Gibson, DVM!";
echo
str_shift($string);
echo
str_shift($string, 50, TRUE);
echo
str_shift($string, -25, FALSE, FALSE);
echo
str_shift($string, 1/3);
echo
str_shift($string, 50, array('lower'=>TRUE, 'digits'=>TRUE));
?>

//===== 结果 =====

Crgre'f 62 crgf (vapy. 0 unzfgref) ybir Qe Fnenu Tvofba, QIZ!
Crgre"f 62 crgf [vapy: 0 unzfgref] ybir Qe Fnenu Tvofba; QIZ?
Jynyl'm 17 jynm (chwf. 5 bugmnylm) fipy Xl Mulub Acvmih, XPG!
Yncna'b 40 yncb (rwlu. 8 qjvbcnab) uxen Ma Bjajq Prkbxw, MEV!
Prgre'f 62 crgf (vapy. 0 unzfgref) ybir De Snenu Gvofba, DVM!

1. 基本参数是字符串和百分比,默认值为 50。接下来的四个参数允许选择要处理的字符类型。我把不太常用的类型放在前面,最明显的类型放在后面,是有原因的。要激活额外字符,您只需 1 个附加参数,否则您需要 4 个参数,还要启用明显的类型。

2. 字母和数字的定义很明显。对于额外字符,我选择了一些在偏移 50% 时有意义的配对,例如 () => [] 或 & => + 等等。当然,您可以根据自己的喜好调整这些字符。

3. 第一步是清理百分比,并允许使用“真实”浮点数,例如 1/3 表示 33.33%。

4. 下一步确保在使用函数时具有很大的灵活性。如前所述,您可以传递 1 个数组,而不是 4 个布尔参数。例如,数组('upper' => TRUE) 将只启用大写字母的更改。

5. 最后,函数遍历每种类型,并根据给定的百分比偏移字符。

我希望您可以使用此函数并用它做一些有趣的事情。旋转字符实际上没有意义,但它很有趣。

Arthur :-)
1
maximius at gmail dot com
17 年前
也许有人会觉得这有用;)

<?
function rotN($s, $n){
$s2 = "";
for($i = 0; $i < strlen($s); $i++){
$char2 = $char = ord($s{$i});
$cap = $char & 32;

$char &= ~ $cap;
$char = $char > 64 && $char < 123 ? (($char - 65 + $n) % 26 + 65) : $char;
$char |= $cap;
if($char < 65 && $char2 > 64 || ($char > 90 && $char < 97 && ($char2 < 91 || $char2 > 96))) $char += 26;
else if($char > 122 && $char2 < 123) $char -= 52;
if(strtoupper(chr($char2)) === chr($char2)) $char = strtoupper(chr($char)); else $char = strtolower(chr($char));
$s2 .= $char;
}
return $s2;
}
?>
它接受任何字符串 $s 和任何 ROT 值 $n。就像 str_rot13 一样,它既是编码器又是解码器。要解码编码的字符串,只需传递 -$n 而不是 $n。
-1
Chris
5 年前
一种使用 rot-n 的简洁、简单的方法。允许进行大量的轻松自定义,并且运行速度很快。此函数使用 ASCII 字符和值。

<?php

function rotn($val, $n) {
$min = 0;
$max = 127;
$final = '';
$new_string = str_split($val);

foreach (
$new_string as $letter) {
$current = ord($letter);
$val = $current+$n;

if (
$val >= $max) {
$val = $val - $max;
}

if (
$val <= $min) {
$val = $val + $min;
}

$current = $val;
$final .= chr($current);
}

return
$final;
}

echo
'Test 123 (4) -> '.rotn("Test 123", 4).'<br>'; // Xiwx$567
echo 'Test 123 (8) -> '.rotn("Test 123", 8).'<br>'; // \m{|(9:;
echo 'Test 123 (-4) -> '.rotn("Test 123", -4).'<br>'; // Paop -./

$value = rotn("Test 123", 8);
echo
'Test 123 (Reverse [8 then -8]) -> '.rotn($value, -8).'<br>'; // Test 123

?>
-2
agente007_1_ at hotmail dot com
9 年前
/**
SALVAJE COMENTARIO EN ESPAÑOL XD
*/

<?php


$cadena
= $_POST['entrada'];

/**convierte en cadena*/
$array = str_split($cadena);

echo
$cadena ."<br>";

for (
$i=0; $i < count($array); $i++) {

if(
$array[$i] >= "A" && $array[$i] <= "M" ){
$letra = ord($array[$i]);
$letra = $letra + 13;
echo
chr($letra);
}

if(
$array[$i] >= "N" && $array[$i] <= "Z" ){
$letra = ord($array[$i]);
$letra = $letra - 13;
echo
chr($letra);
}

}

?>
-4
electro at whatever dot com
17 年前
<?php

/**
* 将每个字符串字符在 ASCII 表中旋转 n 个位置
* 要编码,使用正数 n,要解码,使用负数。
* 当 n = 13 (ROT13) 时,编码和解码 n 可以为正数。
*
* @param string $string
* @param integer $n
* @return string
*/
function rotate($string, $n) {

$length = strlen($string);
$result = '';

for(
$i = 0; $i < $length; $i++) {
$ascii = ord($string{$i});

$rotated = $ascii;

if (
$ascii > 64 && $ascii < 91) {
$rotated += $n;
$rotated > 90 && $rotated += -90 + 64;
$rotated < 65 && $rotated += -64 + 90;
} elseif (
$ascii > 96 && $ascii < 123) {
$rotated += $n;
$rotated > 122 && $rotated += -122 + 96;
$rotated < 97 && $rotated += -96 + 122;
}

$result .= chr($rotated);
}

return
$result;
}

$enc = rotate('string', 6);
echo
"Encoded: $enc<br/>\n";
echo
'Decoded: ' . rotate($enc, -6);

?>
-8
shaunspiller at spammenotgmail dot com
14 年前
这是我实现的 str_rot,它接受自定义偏移量。它比这里的其他实现更快,因为它一次性分配输出字符串,而不是逐个字符地添加。它可以处理任何大小的正负偏移量,并且它修复了所有内容以确保只转换大写和小写字母,并且它们在字母表中正确地环绕。

<?php
function str_rot($s, $n = 13) {
$n = (int)$n % 26;
if (!
$n) return $s;
for (
$i = 0, $l = strlen($s); $i < $l; $i++) {
$c = ord($s[$i]);
if (
$c >= 97 && $c <= 122) {
$s[$i] = chr(($c - 71 + $n) % 26 + 97);
} else if (
$c >= 65 && $c <= 90) {
$s[$i] = chr(($c - 39 + $n) % 26 + 65);
}
}
return
$s;
}
?>
-2
devcoder at gmail dot com
5 年前
我自己的通用 rotN 函数

<?php
function rotN($string, $n = 13)
{
$alphabet = join(range('a', 'z'));
$alen = strlen($alphabet);

$n %= $alen;
if(
$n < 0) {
$n += $alen;
}
if(
$n == 0) {
return
$string;
}

$cycled = substr($alphabet . $alphabet, $n, $alen);
$alphabet = $alphabet . strtoupper($alphabet);
$cycled = $cycled . strtoupper($cycled);
return
strtr($string, $alphabet, $cycled);
}
?>
-5
arwab at surrealwebs dot com
17 年前
这是我的 rot 函数,它无论如何都能工作
<?php
/**
* 对传入的字符串执行旋转算法
*/
function _rot( $str , $dist=13 ){
if( !
is_numeric($dist) || $dist < 0){
$dist = 13;
}

$u_lower = 65; $u_upper = 90;
$l_lower = 97; $l_upper = 122;

$char_count = ($u_upper - $u_lower) +1;

while(
$dist > $char_count ){
$dist -= $char_count;
}

$newstr = '';

for(
$i=0; $i<strlen($str); ++$i){
$c = ord($str[$i]);

/*
* 检查字符是否在我们函数的范围内 (a-zA-z)
* 如果没有,则将其原样附加到字符串中,然后继续执行
* 下一个。
*/
if( $c<$u_lower || $c>$l_upper || ( $c>$u_upper && $c <$l_lower ) ){
$newstr .= chr($c);
continue;
}

$lower = ( $c<=$u_upper?$u_lower:$l_lower);
$upper = ( $c<=$u_upper?$u_upper:$l_upper);

$c += $dist;

if(
$c > $upper){
$c = (($c - $upper) + ($lower-1));
}

$newstr .= chr($c);
}

return
$newstr;
}
?>
-7
steve
11 年前
下面是一个简短的函数,允许您旋转一个字符串,其中包括您选择的非字母字符。

通过运行没有第二个参数的代码,您可以同时混淆和取消混淆。这不是一种安全的加密形式,只是一种快速的方法,可以将内容隐藏起来,以防偶然查看。

function str_rot($s, $n = -1) {
// 按数字旋转一个字符串。
static $letters = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789.,!$*+-?@#'; // 为了能够取消混淆您的字符串,这个字符串的长度需要是 4 的倍数,并且没有重复的字符
$letterLen=round(strlen($letters)/2);
if($n==-1) $n=(int)($letterLen/2); // 找到“旋转中点”
$n = (int)$n % ($letterLen);
if (!$n) return $s;
if ($n < 0) $n += ($letterLen);
//if ($n == 13) return str_rot13($s);
$rep = substr($letters, $n * 2) . substr($letters, 0, $n * 2);
return strtr($s, $letters, $rep);
}

$input="ABC123";
$output=str_rot($input);
echo $input." = ".$output." = ".str_rot($output)."<br>";
-15
peter at NOSPAM jamit dot com
14 年前
这是我的 ROT13 函数,它适用于所有可能的字符,而不仅仅是 ASCII。它可以用于中文、日语等。

<?php

function rot13encrypt ($str) {
return
str_rot13(base64_encode($str));
}

function
rot13decrypt ($str) {
return
base64_decode(str_rot13($str));
}

// 例子

$string = '中國是我的家';

$encrypted = rot13encrypt ($string); // 生成 5Yvg5MlY5cvi5bvE55dR5n62

$decrypted = rot13decrypt ($encrypted); // 生成 中國是我的家

?>
To Top