PHP Conference Japan 2024

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

?>

添加注释

用户贡献的注释 9 条注释

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";
}
?>
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 :-)
peter at NOSPAM jamit dot com
15 年前
这个 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;
}

// 示例

$original = '中國是我的家'; // 表示“中国是我的家”

$encrypted = unicodeRotN($string, 13); // 为團昼戞皑寃 表示“Ñ Ai injustice for the Mission Day”(谷歌翻译)

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

?>
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。
Chris
6 年前
一种使用 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

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

<?php


$cadena
= $_POST['entrada'];

/**转换为字符串*/
$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);
}

}

?>
devcoder at gmail dot com
6 年前
我自己的通用 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);
}
?>
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);

?>
[email protected]
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;
}
?>
To Top