Шифруем запрещенные слова с помощью алгоритма ROT13 в WordPress

В информатике существует бесчисленное множество алгоритмов по шифрованию данных. Один из не самых известных и не самых распространенных алгоритмов – это ROT13, являющийся производным от шифра Цезаря.

В этом руководстве мы рассмотрим шифрование ROT13, а также разберем основы его работы. Мы посмотрим, как можно запрограммировать текст (текстовые строки) в ROT13 с помощью PHP. Наконец, мы напишем плагин для WordPress, который будет проводить сканирование записей на наличие запрещенных слов из черного списка и менять их на шифр ROT13.

Если у вас есть блог с большим количеством авторов, либо определенная группа пользователей имеет права на публикацию записей, то в таком случае плагин, который позволяет зашифровать или полностью удалить несоответствующие слова, окажется очень полезным.

Перед тем, как начать, давайте скажем пару слов о ROT13. Этот алгоритм никогда не должен использоваться для шифрования важных данных. Несмотря на то, что некоторые считают этот алгоритм методикой шифрования, на самом деле он является самым базовым примером создания шифра, эдаким «Hello World» от мира шифрования. Он может быть очень легко разгадан, и потому он никогда не используется для данных, которые надо защитить из соображений безопасности. А поскольку наша цель – это не защита данных, а скрытие ругани, то он прекрасно пригодится для нашего примера.

Введение

ROT13 (короткая версия от «rotate by 13 places», иногда представимая в виде ROT-13) является простой методикой шифрования для английского языка. Каждая буква меняется на букву, стоящую со сдвигом на 13 позиций в алфавите. Т.е. A переходит в N, B переходит в O, и так далее до M, которая переходит в Z. Затем последовательность продолжается с начала алфавита: N переходит в A, O переходит в B, и так далее до Z, которая переходит в M.

Главное преимущество ROT13 перед другими rot(N) техниками (где N – это целое число, обозначающее сдвиг на N алфавитных позиций в шифре Цезаря) состоит в том, что он является обратным, т.е. тот же самый алгоритм может применяться как для шифрования, так и для дешифрования данных.

Ниже представлена ROT13 таблица:

| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
--------------------------------------------------------------------------------------------------------  
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M |

Если мы зашифруем домен smashingmagazine.com в ROT13, то получим в итоге fznfuvatzntnmvar.pbz, а предложение «Why did the chicken cross the road?» превратится в «Jul qvq gur puvpxra pebff gur ebnq?»

Обратите внимание, что в ROT13 шифруются только буквы алфавита. Цифры, знаки, пробелы и все другие символы остаются без изменения.

Перевод строк в ROT13 в PHP

PHP включает в себя функцию str_rot13() для конвертации строк в значение ROT13. Чтобы зашифровать текст в ROT13 при помощи данной функции, передайте текст в качестве аргумента этой функции:

<?php

echo str_rot13('smashingmagazine.com'); // fznfuvatzntnmvar.pbz

echo str_rot13('The best web design and development blog'); // Gur orfg jro qrfvta naq qrirybczrag oybt

Используем ROT13 в WordPress

Вооружившись этими знаниями, я решил подумать над тем, как их применить в WordPress. В итоге я создал плагин, который кодирует запрещенные слова, найденные в записях, используя ROT13.

Плагин состоит из поля textearea (которое находится на странице настроек), в котором вы вводите запрещенные слова, после чего они сохраняются в базе данных WordPress для последующей проверки в записях.

Давайте приступим к написанию плагина.

Создание плагина

Для начала вводим заголовок плагина.

<?php

/*
Plugin Name: Rot13 Words Blacklist
Plugin URI: http://smashingmagazine.com/
Description: A simple plugin that detects and encrypts blacklisted words in ROT13
Version: 1.0
Author: Agbonghama Collins
Author URI: http://w3guy.com
Text Domain: rot13
Domain Path: /lang/
License: GPL2
*/

Как уже было сказано выше, плагин будет иметь страницу настроек с полем textarea, которое будет сохранять запрещенные слова в базу данных WordPress (в таблицу options).

Ниже представлен скриншот того, как будет выглядеть страница настроек плагина в админке.

rot13-plugin-settings-page-opt

Теперь давайте перейдем к созданию страницы опций при помощи Settings API.

Создание страницы опций

Для начала мы создадим пункт подменю в основном меню Settings (Параметры) при помощи add_options_page() с родительской функцией, подцепленной к действию add_action.

add_action( 'admin_menu', 'rot13_plugin_menu' );

/**
 * Add submenu to main Settings menu
 */
function rot13_plugin_menu() {
	add_options_page(
		__( 'Rot13 Blacklisted Words', 'rot13' ),
		__( 'Rot13 Blacklisted Words', 'rot13' ),
		'manage_options',
		'rot13-words-blacklist',
		'rot13_plugin_settings_page'
	);
}

Пятый параметр add_options_page() – это название функции (rot13_plugin_settings_page), которая вызывает для вывода контента на странице.

Ниже приведен код rot13_plugin_settings_page().

/**
 * Output the contents of the settings page.
 */
function rot13_plugin_settings_page() {
	echo '<div class="wrap">';
	echo '<h2>', __( 'Rot13 Blacklisted Words', 'rot13' ), '</h2>';
	echo '<form action="options.php" method="post">';
	do_settings_sections( 'rot13-words-blacklist' );
	settings_fields( 'rot13_settings_group' );
	submit_button();
}

Затем мы добавляем новую секцию к странице Параметров с помощью add_settings_section(). Поле textarea, которое мы уже упомянули ранее, будет добавлено к данной секции с помощью add_settings_field(). Наконец, параметры регистрируются через register_setting().

Ниже представлен код для add_settings_section(), add_settings_field() и register_setting().

// Add the section
	add_settings_section(
		'rot13_setting_section',
		'',
		'rot13_setting_section_callback_function',
		'rot13-words-blacklist'
	);


	// Add the textarea field to the section.
	add_settings_field(
		'blacklisted_words',
		__( 'Blacklisted words', 'rot13' ),
		'rot13_setting_callback_function',
		'rot13-words-blacklist',
		'rot13_setting_section'
	);

	// Register our setting so that $_POST handling is done for us
	register_setting( 'rot13_settings_group', 'rot13_plugin_option', 'sanitize_text_field' );

Три функции, представленные выше, должны быть добавлены в функцию и подцеплены к действию admin_init:

/**
 * Hook the Settings API to 'admin_init' action
 */
function rot13_settings_api_init() {
	// Add the section
	add_settings_section(
		'rot13_setting_section',
		'',
		'rot13_setting_section_callback_function',
		'rot13-words-blacklist'
	);


	// Add the textarea field to the section
	add_settings_field(
		'blacklisted_words',
		__( 'Blacklisted words', 'rot13' ),
		'rot13_setting_callback_function',
		'rot13-words-blacklist',
		'rot13_setting_section'
	);

	// Register our setting so that $_POST handling is done for us
	register_setting( 'rot13_settings_group', 'rot13_plugin_option', 'sanitize_text_field' );
}

add_action( 'admin_init', 'rot13_settings_api_init' );

Ниже приведен код для функций rot13_setting_callback_function() и rot13_setting_section_callback_function(), которые выведут поле textarea и описание поля соответственно (в самом верху раздела).

/**
 * Add a description of the field to the top of the section
 */
function rot13_setting_section_callback_function() {
	echo '<p>' . __( 'Enter a list of words to blacklist, separated by commas (,)', 'rot13' ) . '</p>';
}

/**
 * Callback function to output the textarea form field
 */
function rot13_setting_callback_function() {
	echo '<textarea rows="10" cols="60" name="rot13_plugin_option" class="code">' . esc_textarea( get_option( 'rot13_plugin_option' ) ) . '</textarea>';
}

Мы создали страницу настроек для плагина. Далее нам нужно заставить плагин обнаруживать запрещенные слова и шифровать их с помощью ROT13.

Обнаружение запрещенных слов и их шифрование в ROT13

  • Вот обзор того, как мы будем искать запрещенные слова в записи WordPress:
  • Контент записи разбивается на отдельные слова и сохраняется в массив ($post_words).
  • Запрещенные слова, которые были сохранены в базу данных, восстанавливаются из нее. Затем они тоже разбиваются на отдельные слова и заносятся в массив ($blacklisted_words).
  • Мы проходим по массиву $post_words и проверяем, есть ли в нем слова, внесенные в черный список.
  • Если запрещенное слово найдено, str_rot13() кодирует его в ROT13.

Самое время написать PHP-функцию rot13_filter_post_content(), которая будет фильтровать контент записи и затем выявлять запрещенные слова, шифруя их в ROT13.

Ниже приведен код фильтра записи.

/**
 * Encrypt every blacklisted word in ROT13
 *
 * @param $content string post content to filter
 *
 * @return string
 */
function rot13_filter_post_content( $content ) {

	// Get the words marked as blacklisted by the plugin
	$blacklisted_words = esc_textarea( get_option( 'rot13_plugin_option' ) );

    // If no blacklisted word are defined, return the post's content.
	if ( empty( $blacklisted_words ) ) {
		return $content;
	}

	else {

		// Ensure we are dealing with "posts", not "pages" or any other content type.
		if ( is_singular( 'post' ) ) {

			// Confine each word in a post to an array
			$post_words = preg_split( "/\b/", $content );

			// Break down the post's contents into individual words
			$blacklisted_words = explode( ',', $blacklisted_words );

			// Remove any leading or trailing white space
			$blacklisted_words = array_map(
				function ( $arg ) {
					return trim( $arg );
				},

				$blacklisted_words
			);


			// Iterate over the array of words in the post
			foreach ( $post_words as $key => $value ) {

				// Iterate over the array of blacklisted words
				foreach ( $blacklisted_words as $words ) {

					// Compare the words, being case-insensitive
					if ( strcasecmp( $post_words[ $key ], $words ) == 0 ) {

						// Encrypt any blacklisted word
						$post_words[ $key ] = '<del>' . str_rot13( $value ) . '</del>';
					}
				}
			}

			// Convert the individual words in the post back into a string or text
			$content = implode( '', $post_words );
		}

		return $content;
	}
}


add_filter( 'the_content', 'rot13_filter_post_content' );

Код, стоящий выше фильтра, не самый сложный, однако я все же постараюсь раскрыть его в деталях.

is_singular( ‘post’ ) – условный тег, который проверяет, что мы работаем с записью, а не со страницей и не с другим типом контента.

С помощью preg_split() мы разбиваем контент записи на отдельные слова и сохраняем их в массив. Определение новых слов происходит при помощи паттерна \b, который определяет границу слова.

Список запрещенных слов получается из базы данных через get_option(); в качестве названия опции задается rot13_plugin_option.

На скриншоте, представленном выше, мы можем видеть, что список запрещенных слов разделен запятой. Функция explode вносит запрещенные слова в массив, ориентируясь на запятые.

Через array_map() мы применяем к массиву $blacklisted_words специальное выражение, которое удаляет лишние пробелы из значений массива (списка отдельных запрещенных слов).

Конструкция foreach проходит по словам записи и проверяет, было ли это слово представлено в массиве запрещенных слов. Любое запрещенное слово, которое будет обнаружено, шифруется в ROT13 и вносится в тег del.

Массив $post_words преобразуется обратно в строку или текст и затем выводится.

Наконец, функция подцепляется к фильтру the_content.

Ниже представлен скриншот записи со словами love и forever в черном списке.

post-with-blacklisted-word-opt

Конечно, на практике это применимо мало, но зато представлена сама идея такого подхода, а это уже может быть полезно для реализации самых разных идей.

Источник: http://www.smashingmagazine.com

Блог про WordPress
Комментарии: 2
  1. Алексей

    Ух ты какая штуковина. спасибо большое автору за урок и мой первый плагин, в котором я копался. Может в будущем буду использовать.

  2. Вячеслав

    Здравствуйте! Подскажите готовый плагин для wordpress. У меня на сайте стоит РСЯ. РСЯ даёт блокировать не более 1000 доменных имён конкурентов и вот у меня закончился этот лимит. Хочу найти плагин, чтобы в нём можно было блокировать определённые слова и url. По идее должно сработать и для РСЯ. Может вы что-нибудь подскажете как это сделать? С уважением Вячеслав.

Добавить комментарий для Вячеслав Отменить ответ

Получать новые комментарии по электронной почте.