简体   繁体   English

更改字符但保持长度

[英]Change characters but keep length

I am migrating sensitive data to a database, and I need to hide details of the text. 我正在将敏感数据迁移到数据库,并且需要隐藏文本的详细信息。 We would like to keep the volume and length of the text, but change the meaning. 我们希望保留文本的大小和长度,但要更改其含义。

For example: 例如:

"James has been well received, and should be helped when ever he finds it hard to speak" “詹姆斯受到了好评,只要他觉得很难说话就应该得到帮助”

should change to: 应该更改为:

"jhdfy dfw aslk dfe kjdfkjd, kjf kjdsf df iotryy erhr lsdj jf ytwe it kjdf tr kjsdd" “ jhdfy dfw aslk dfe kjdfkjd,kjf kjdsf df iotryy erhr lsdj jf ytwe it kjdf tr kjsdd”

Is there a way to update all rows, set the column text to this random type text? 有没有一种方法可以更新所有行,将列文本设置为此随机类型的文本? Really only want to change charactors (az, AZ), and keep the rest. 真的只想更改字符(az,AZ),并保留其余字符。

One option is to use a bunch of nested replaces . 一种选择是使用一堆嵌套的replaces。 . . but that would probably hit on the maximum number of nested functions. 但这可能会影响嵌套函数的最大数量。

You could write a painful query using outer apply : 您可以使用outer apply编写痛苦的查询:

select 
from t outer apply
     (select replace(t.col, 'a', 'z') as col1) outer apply
     (select replace(col1, 'b', 'y') ) outer apply
     . . .

However, you might want to write your own function. 但是,您可能需要编写自己的函数。 In other databases, this is called translate() (after the Unix command). 在其他数据库中,这被称为translate() (在Unix命令之后)。 If you Google SQL Server translate , I think you'll find examples on the web. 如果您使用Google SQL Server translate ,我想您会在网络上找到示例。

One way is to split the string character by character and replace each row with a random string. 一种方法是逐字符拆分字符串,并用随机字符串替换每一行。 And then concatenate them back to get the desired output 然后将它们串联起来以获得所需的输出

DECLARE @str VARCHAR(MAX) = 'James has been well received, and should be helped when ever he finds it hard to speak'

;WITH Cte(orig, random) AS(
SELECT
    SUBSTRING(t.a, v.number + 1, 1),
    CASE 
        WHEN SUBSTRING(t.a, v.number + 1, 1) LIKE '[a-z]' 
            THEN CHAR(ABS(CHECKSUM(NEWID())) % 25 + 97)
        ELSE SUBSTRING(t.a, v.number + 1, 1) 
    END
FROM (SELECT @str) t(a)
CROSS JOIN master..spt_values v
WHERE
    v.number < LEN(t.a)
    AND v.type = 'P'
)
SELECT 
    OrignalString = @str,
    RandomString = (
        SELECT '' + random 
        FROM Cte FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'
    )

TRY IT HERE 在这里尝试

OK this is possible using a user defined function (UDF) and a view. 好的,这可以使用用户定义的函数(UDF)和视图来实现。 SQL Server does not allow random number generation in a UDF but does allow it in a view. SQL Server不允许在UDF中生成随机数,但允许在视图中生成随机数。 Ref: http://blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/ 参考: http : //blog.sqlauthority.com/2012/11/20/sql-server-using-rand-in-user-defined-functions-udf/

So here is the solution 所以这是解决方案

CREATE VIEW [dbo].[rndView]
AS
    SELECT RAND() rndResult

GO
CREATE FUNCTION [dbo].[RandFn]()
    RETURNS float
AS
BEGIN
    DECLARE @rndValue float
    SELECT @rndValue = rndResult
    FROM rndView
    RETURN @rndValue
END

GO

CREATE FUNCTION [dbo].[randomstring] ( @stringToParse VARCHAR(MAX))
RETURNS
     varchar(max)
AS
BEGIN
/*
A = 65
Z = 90

a = 97
z = 112
declare @stringToParse VARCHAR(MAX) = 'James has been well received, and should be helped when ever he finds it hard to speak'
Select [dbo].[randomstring] ( @stringToParse )
go
Update SpecialTable
Set SpecialString = [dbo].[randomstring] (SpecialString)
go

*/
    declare @StringToreturn varchar(max) = ''
    declare @charCounter int = 1
    declare @len int = len(@stringToParse) 
    declare @thisRand int 
    declare @UpperA int = 65
    declare @UpperZ int = 90

    declare @LowerA int = 97
    declare @LowerZ int = 112
    declare @thisChar char(1)
    declare @Random_Number float
    declare @randomChar char(1)
    WHILE @charCounter < @len 
    BEGIN
        SELECT @thisChar = SUBSTRING(@stringToParse, @charCounter, 1)
        set @randomChar = @thisChar
        --print @randomChar 
        SELECT @Random_Number = dbo.RandFn()
        --print @Random_Number 
        --only swap if a-z or A-Z
        if ASCII(@thisChar) >= @UpperA and ASCII(@thisChar) <= @UpperZ begin
        --upper case

          set @thisRand = @UpperA +  (@Random_Number * convert(float, (@UpperZ-@UpperA)))
          set @randomChar = CHAR(@thisRand)
          --print @thisRand 
        end
        if ASCII(@thisChar) >= @LowerA and ASCII(@thisChar) <= @LowerZ begin
        --upper case
          set @thisRand = @LowerA +  (@Random_Number *  convert(float, (@LowerZ-@LowerA)))
          set @randomChar = CHAR(@thisRand)  
        end
        --print @thisRand 

        --print @randomChar 
        set @StringToreturn = @StringToreturn +  @randomChar        
        SET @charCounter = @charCounter + 1   
    END

    --Select * from @returnList
    return  @StringToreturn
END



GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM