2024 PHP Conference Japan

str_rot13

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

str_rot13對字串執行 rot13 轉換

說明

str_rot13(字串 $string): 字串

string 參數執行 ROT13 編碼,並返回結果字串。

ROT13 編碼只是將每個字母在字母表中移動 13 個位置,同時保留非字母字元不變。編碼和解碼由同一個函式完成,傳遞編碼後的字串作為參數將返回原始版本。

參數

字串

輸入字串。

傳回值

返回給定字串的 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
函式 str_rot($s, $n = 13) {
靜態
$letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$n = (int)$n % 26;
若 (!
$n) 傳回 $s;
若 (
$n == 13) 傳回 str_rot13($s);
對於 (
$i = 0, $l = strlen($s); $i < $l; $i++) {
$c = $s[$i];
若 (
$c >= 'a' && $c <= 'z') {
$s[$i] = $letters[(ord($c) - 71 + $n) % 26];
} 否則若 (
$c >= 'A' && $c <= 'Z') {
$s[$i] = $letters[(ord($c) - 39 + $n) % 26 + 26];
}
}
傳回
$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
//================================================== STRING ROTATE EXPANDED
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;
}

//===== USAGE =====

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);

//===== EXAMPLES =====

$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 (相當於 5 bugmnylm) 來自 Xl Mulub Acvmih, XPG!
Yncna'b 40 yncb (大約 8 qjvbcnab) 來自 Ma Bjajq Prkbxw, MEV!
Prgre'f 62 crgf (大概是 0 unzfgref) 來自 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;
}

// example

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

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

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

$value = rotn("Test 123", 8);
echo
'測試 123 (反轉 [8 然後 -8]) -> '.rotn($value, -8).'<br>'; // Test 123

?>
agente007_1_ at hotmail dot com
9 年前
/**
西班牙文的奇怪註解 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 值。
* 使用 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 = $rotated - 90 + 64;
$rotated < 65 && $rotated = $rotated - 64 + 90;
} elseif (
$ascii > 96 && $ascii < 123) {
$rotated += $n;
$rotated > 122 && $rotated = $rotated - 122 + 96;
$rotated < 97 && $rotated = $rotated - 96 + 122;
}

$result .= chr($rotated);
}

return
$result;
}

$enc = rotate('string', 6);
echo
"已編碼: $enc<br/>\n";
echo
'已解碼: ' . rotate($enc, -6);

?>
arwab at surrealwebs dot com
17 年前
這是我的旋轉函式,它可以運作
<?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