在SQL中为一组行生成相同的随机字符串

3

我正在尝试为测试目的在SQL数据库中“混淆”数据。我有一个单独的表格里面有一个字段,我希望这个字段的值被替换为随机字符串,但是相同的字符串必须具有相同的值。例如:

Cat
Dog
Cat
Fish
Monkey

需替换为

YuW -- same
JiK
YuW -- same
IPoQ
KYiLwY

我不希望这个过程是可逆的(所以不能使用 ROT13 等方法)

编辑:我需要它保持相同的长度。这个数据库将用于性能测试,我希望使用真实的字符串大小。


你使用什么来生成随机字符串? - RBarryYoung
base64是可逆的,所以不行 :( - esac
5个回答

3

您应该使用哈希算法

SELECT HashBytes('MD5', yourcolumnname)

这将为您提供一种不可逆的“混淆”,相同的输入值将返回相同的值。
编辑:如果您不想使用MD5 HashBytes可以处理MD2、MD4、MD5、SHA、SHA1或SHA2。
编辑2:要保持相同的长度(至少达到哈希值的长度),请执行以下操作:
SELECT (SELECT SUBSTRING(HASHBYTES('MD5',[yourcolumnname]),0,len([yourcolumnname])))

如果您希望字符串保持机密,不要使用MD5。 - Paolo
抱歉,我更新了我的问题。我已经尝试过这种方法,但所有字符串大小都相同,数据大小变得完全相同,会影响性能测试。 - esac

2
如果只是为了测试和兴趣而言,我会这样做:
1.将不同的记录放入临时表中,并添加一个新列,我们称其为“[随机化]”。 2.生成所需的随机文本,并确保其与实际文本具有相同的LEN()(使用LEFT(),RIGHT(),SUBSTRING()或任何其他函数来完成)。 3.查询您的实际表格并在谓词上加入它们。 4.使用随机列更新您的实际表格。
不确定是否符合您的需求。

谢谢。目前我选择了最受欢迎的评论,它符合我的需求。但是,我将努力将其推广到我们所有的测试数据库,并且我认为你的机制将是最好的。我只需要编写代码并进行测试。 - esac

1
这里有一种方法:对字符串进行 checksum() 并选择前 个字符。
select left(cast(checksum(name) as varchar(255)), 10)

结果只会是数字字符串,但这似乎符合您的要求。

这非常接近我想要的,到目前为止看起来是最好的选择。不过我真的希望能够保留字母作为字母。 - esac
@esac,你总是可以在第二步将数字替换为字母。这样做会使其更加不可逆,因为现在你不知道BB还是0 - Juan Carlos Oropeza

1
您可以使用哈希函数替换值。您可能希望保留一个键,以便可以反转函数。话虽如此,听起来您只是想混淆数据。在大多数SQL语言中,您可以使用任何数量的哈希函数来实现这一点。您可以考虑md5、sha1、sha2或其他哈希函数。
在SQL Server中,hashbytes具有MD2、MD4、MD5、SHA、SHA1或SHA2。
您可以像这样混淆数据:
select HASHBYTES('MD5', 'Sample String to hash ') from x;
select HASHBYTES('SHA1', 'Sample String to hash ') from x;

这些算法旨在减少碰撞。MD5的安全性较低。 当您的数据不敏感时,我建议使用CRC32,它返回给定字符串的循环冗余校验值作为32位无符号值。它可以用作哈希函数,但同样不安全。它可以生成更小的字符串,因此在可逆性不是问题时更有效率。
select CHECKSUM('string') from x;

0

我很好奇...这个怎么样:

编辑:您可以使用此方法为每个不同的现有值找到“新值”...

CREATE VIEW Get_NewID
AS
SELECT NEWID() AS MyNewID
GO

CREATE FUNCTION dbo.RandomLetters(@Length INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @rslt VARCHAR(MAX);
WITH TwentySixNumbers AS
(
    --a tally table
    SELECT TOP 26 ROW_NUMBER() OVER(ORDER BY object_id) AS nmbr
                 ,(SELECT MyNewID FROM Get_NewID) AS sort
    FROM sys.objects
)
,TwentySixLetters AS
(
    SELECT nmbr,sort,CHAR(nmbr+64) AS letter
    FROM TwentySixNumbers
)
SELECT @rslt=
(
    SELECT TOP (@Length) letter
    FROM TwentySixLetters
    ORDER BY sort
    FOR XML PATH(''),TYPE
).value('.','varchar(max)');
RETURN @rslt;
END
GO

--Here you create 10 different strings of seven letters
--pass as length the length of your text
WITH TenNumbers AS
(
    --a tally table
    SELECT TOP 10 ROW_NUMBER() OVER(ORDER BY object_id) AS nmbr
    FROM sys.objects
)
SELECT dbo.RandomLetters(7)
FROM TenNumbers;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接