GOAL: I have to obfuscate sensible data on a SQL Server database. Dynamic Data Masking is not an option. Data shuffle is not an option. The only option is Data Scramble.
SOLUTION: In the most hidden meander of the internet I found a very nice piece of code that can easily adapt to most of the data type:
-------------------------------------------------
--A view to give you Random Values
CREATE VIEW dbo.random(value) AS SELECT RAND();
GO
-------------------------------------------------
--Randomization Procedure
CREATE FUNCTION dbo.fnRandomizedText (
@OldValue AS VARCHAR(MAX)
)RETURNS VARCHAR(MAX)
BEGIN
DECLARE @NewValue AS VARCHAR(MAX)
DECLARE @nCount AS INT
DECLARE @cCurrent AS CHAR(1)
DECLARE @cScrambled AS CHAR(1)
DECLARE @Random AS REAL
SET @NewValue = ''
SET @nCount = 0
WHILE (@nCount <= LEN(@OldValue))
BEGIN
SELECT @Random = value FROM random
SET @cCurrent = SUBSTRING(@OldValue, @nCount, 1)
IF ASCII(@cCurrent) BETWEEN ASCII('a') AND ASCII('z')
SET @cScrambled = CHAR(ROUND(((ASCII('z') - ASCII('a') - 1) * @Random + ASCII('a')), 0))
ELSE IF ASCII(@cCurrent) BETWEEN ASCII('A') AND ASCII('Z')
SET @cScrambled = CHAR(ROUND(((ASCII('Z') - ASCII('A') - 1) * @Random + ASCII('A')), 0))
ELSE IF ASCII(@cCurrent) BETWEEN ASCII('0') AND ASCII('9')
SET @cScrambled = CHAR(ROUND(((ASCII('9') - ASCII('0') - 1) * @Random + ASCII('0')), 0))
ELSE
SET @cScrambled = @cCurrent
SET @NewValue = @NewValue + @cScrambled
SET @nCount = @nCount + 1
END
RETURN LTRIM(RTRIM(@NewValue))
END
GO
-------------------------------------------------
Thanks to this function every name or surname can be scrambled this way:
SELECT
[FirstName],
UserName = dbo.fnRandomizedText([FirstName])
FROM [AdventureWorks2014].[Person].[Person]
| FirstName | UserName |
|---|---|
| Ken | Tkm |
| Terri | Pggkg |
| Roberto | Thewgnu |
| Rob | Trs |
| Gail | Dgbp |
And with the same function I can scramble e-mail addresses:
SELECT
[EmailAddress]
,email = dbo.fnRandomizedText([EmailAddress])
FROM [AdventureWorks2014].[Person].[EmailAddress]
| EmailAddress | |
|---|---|
| [email protected] | [email protected] |
| [email protected] | [email protected] |
| [email protected] | [email protected] |
| [email protected] | [email protected] |
| [email protected] | [email protected] |
This is an amazing piece of code and I would like to add the option to scramble dates.
Is there a way to scramble in the same way dates this way:
| Dates | New_Dates |
|---|---|
| 11/09/2003 | 12/01/1995 |
| 12/12/2021 | 13/02/1956 |
| 30/05/1998 | 23/03/1988 |
| 14/01/1984 | 01/02/1980 |
That might not be easy because the DataType for dates is much more complex. And I cannot tell how I can approach this problem. Any suggestion?