According to Wikipedia, here below is the definition of the algorithm:
ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet. ROT13 is a special case of the Caesar cipher, developed in ancient Rome.
ROT47 is a derivative of ROT13 which, in addition to scrambling the basic letters, also treats numbers and common symbols. Instead of using the sequence A–Z as the alphabet, ROT47 uses a larger set of characters from the common character encoding known as ASCII. Specifically, the 7-bit printable characters, excluding space, from decimal 33 '!' through 126 '~', 94 in total, taken in the order of the numerical values of their ASCII codes, are rotated by 47 positions, without special consideration of case. For example, the character A is mapped to p, while a is mapped to 2.
I already implemented it in C++ but this time, I have implemented it in SQL Server. Here below is the user-defined function I wrote:
CREATE FUNCTION [dbo].[ROT47]
(
@PLAIN_TEXT nvarchar(MAX)
)
RETURNS nvarchar(MAX)
AS
BEGIN
DECLARE @ENCRYPTED_TEXT nvarchar(MAX) = N''
DECLARE @LENGTH_TEXT int = 0
DECLARE @c nvarchar = N''
DECLARE @i int = 1
SET @LENGTH_TEXT = LEN(@PLAIN_TEXT)
WHILE (@i <= @LENGTH_TEXT)
BEGIN
SET @c = SUBSTRING(@PLAIN_TEXT, @i, 1)
IF (ASCII(@c) BETWEEN ASCII(N'!') AND ASCII(N'~'))
BEGIN
SET @c = char(ASCII(N'!') + (ASCII(@c) - ASCII(N'!') + 47) % 94)
SET @ENCRYPTED_TEXT = @ENCRYPTED_TEXT + @c
END
SET @i = @i + 1
END
RETURN @ENCRYPTED_TEXT
END
Below is the query I wrote to test my UDF:
DECLARE @PLAIN_TEXT nvarchar(MAX) = N'HelloWorld'
DECLARE @ENCRYPTED_TEXT nvarchar(MAX)
DECLARE @DECRYPTED_TEXT nvarchar(MAX)
SET @ENCRYPTED_TEXT = ( SELECT dbo.ROT47(@PLAIN_TEXT) )
SET @DECRYPTED_TEXT = ( SELECT dbo.ROT47(@ENCRYPTED_TEXT) )
SELECT @PLAIN_TEXT AS PLAIN_TEXT,
@ENCRYPTED_TEXT AS ENCRYPTED_TEXT,
@DECRYPTED_TEXT AS DECRYPTED_TEXT
As expected, the above query gives the following result:
+--------------+------------------+------------------+
| PLAIN_TEXT | ENCRYPTED_TEXT | DECRYPTED_TEXT |
+--------------+------------------+------------------+
| HelloWorld | w6==@(@C=5 | HelloWorld |
+--------------+------------------+------------------+
What do you think about my implementation ? Is there a way to improve it ? I know loops are things you're trying to avoid in SQL Server but is there a way to avoid using a loop in my case ?