14 Stimmen

Verschleiern / Maskieren / Verschlüsseln von persönlichen Informationen

Ich bin auf der Suche nach einer selbstentwickelten Möglichkeit, Produktionsdaten für die Verwendung in Entwicklung und Test zu verschlüsseln. Ich habe ein paar Skripte erstellt, die zufällige Sozialversicherungsnummern erzeugen, Geburtsdaten verschieben, E-Mails verschlüsseln usw. Aber beim Versuch, Kundennamen zu verschlüsseln, bin ich gegen eine Wand gestoßen. Ich möchte die echten Namen beibehalten, damit wir sie weiterhin verwenden oder suchen können, also scheidet die Erzeugung zufälliger Buchstaben aus. Bisher habe ich versucht, eine temporäre Tabelle mit allen Nachnamen in der Tabelle zu erstellen und dann die Kundentabelle mit einer zufälligen Auswahl aus der temporären Tabelle zu aktualisieren. Etwa so:

DECLARE @Names TABLE (Id int IDENTITY(1,1),[Name] varchar(100))

/* Scramble the last names (randomly pick another last name) */
INSERT @Names SELECT LastName FROM Customer ORDER BY NEWID();
WITH [Customer ORDERED BY ROWID] AS
(SELECT ROW_NUMBER() OVER (ORDER BY NEWID()) AS ROWID, LastName FROM Customer)
UPDATE [Customer ORDERED BY ROWID] SET LastName=(SELECT [Name] FROM @Names WHERE ROWID=Id)

Dies hat im Test gut funktioniert, ist aber bei größeren Datenmengen (>20 Minuten für 40K Zeilen) völlig unbrauchbar.

Wie würden Sie Kundennamen verschlüsseln, ohne die echten Namen und die Bedeutung der Produktionsdaten zu verändern?

UPDATE : Es passiert immer wieder, dass man versucht, alle Informationen in den Beitrag zu packen, und dabei etwas Wichtiges vergisst. Diese Daten werden auch in unseren öffentlich zugänglichen Verkaufs- und Demoumgebungen verwendet. Einige der Antworten entsprechen dem, was ich zu tun versuche, nämlich die Namen zu "tauschen", aber meine Frage ist wörtlich, wie man in T-SQL codiert?

6voto

Peter Hoffmann Punkte 52200

Ich benutze generierte Daten . Es ist ein Open-Source-PHP-Skript, das alle Arten von Dummy-Daten erzeugen kann.

2voto

mnemotronic Punkte 725

Ich verwende eine Methode, bei der die Zeichen im Namen durch andere Zeichen ersetzt werden, die im gleichen "Bereich" der Häufigkeit der Verwendung in englischen Namen liegen. Offenbar ist die Verteilung der Zeichen in Namen anders als im normalen Umgangsenglisch. Zum Beispiel kommen "x" und "z" in 0,245 % der Fälle vor, also werden sie ausgetauscht. Das andere Extrem ist, dass "w" 5,5 % der Zeit verwendet wird, "s" 6,86 % und "t" 15,978 %. Ich ändere "s" in "w", "t" in "s" und "w" in "t". Die Vokale "aeio" halte ich in einer separaten Gruppe, damit ein Vokal nur durch einen anderen Vokal ersetzt wird. In ähnlicher Weise werden "q", "u" und "y" überhaupt nicht ersetzt. Meine Gruppeneinteilung und Entscheidungen sind völlig subjektiv.

Am Ende hatte ich 7 verschiedene "Gruppen" von 2-5 Charakteren, die hauptsächlich auf der Häufigkeit basieren. Charaktere innerhalb jeder Gruppe werden mit anderen Charakteren in derselben Gruppe ausgetauscht.

Das Ergebnis sind Namen, die irgendwie so aussehen, als ob sie Namen wären, aber nicht von hier".

Original name     Morphed name
Loren             Nimag
Juanita           Kuogewso
Tennyson          Saggywig
David             Mijsm
Julie             Kunewa

Hier ist das von mir verwendete SQL, das eine "TitleCase"-Funktion enthält. Es gibt 2 verschiedene Versionen des "gemorphten" Namens, die auf unterschiedlichen Häufigkeiten von Buchstaben basieren, die ich im Internet gefunden habe.

--    from     https://stackoverflow.com/a/28712621

-- Convert and return param as Title Case

CREATE FUNCTION [dbo].[fnConvert_TitleCase] (@InputString VARCHAR(4000) )
RETURNS VARCHAR(4000)AS
BEGIN
DECLARE @Index INT
DECLARE @Char CHAR(1)
DECLARE @OutputString VARCHAR(255)

SET @OutputString = LOWER(@InputString)
SET @Index = 2
SET @OutputString = STUFF(@OutputString, 1, 1,UPPER(SUBSTRING(@InputString,1,1)))

WHILE @Index <= LEN(@InputString)
BEGIN
   SET @Char = SUBSTRING(@InputString, @Index, 1)
   IF @Char IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&','''','(','{','[','@')
      IF @Index + 1 <= LEN(@InputString)
      BEGIN
         IF @Char != ''''  OR  UPPER(SUBSTRING(@InputString, @Index + 1, 1)) != 'S'
            SET @OutputString = STUFF(@OutputString, @Index + 1, 1,UPPER(SUBSTRING(@InputString, @Index + 1, 1)))
      END
         SET @Index = @Index + 1
      END

   RETURN ISNULL(@OutputString,'')

END
Go

--    00.045 x 0.045%
--    00.045 z 0.045%
--
--    Replace(Replace(Replace(TS_NAME,'x','#'),'z','x'),'#','z')
--
--    00.456 k 0.456%
--    00.511 j 0.511%
--    00.824 v 0.824%
--    kjv
--    Replace(Replace(Replace(Replace(TS_NAME,'k','#'),'j','k'),'v','j'),'#','v')
--
--    01.642 g 1.642%
--    02.284 n 2.284%
--    02.415 l 2.415%
--    gnl
--    Replace(Replace(Replace(Replace(TS_NAME,'g','#'),'n','g'),'l','n'),'#','l')
--
--    02.826 r 2.826%
--    03.174 d 3.174%
--    03.826 m 3.826%
--    rdm
--    Replace(Replace(Replace(Replace(TS_NAME,'r','#'),'d','r'),'m','d'),'#','m')
--
--    04.027 f 4.027%
--    04.200 h 4.200%
--    04.319 p 4.319%
--    04.434 b 4.434%
--    05.238 c 5.238%
--    fhpbc
--    Replace(Replace(Replace(Replace(Replace(Replace(TS_NAME,'f','#'),'h','f'),'p','h'),'b','p'),'c','b'),'#','c')
--
--    05.497 w 5.497%
--    06.686 s 6.686%
--    15.978 t 15.978%
--    wst
--    Replace(Replace(Replace(Replace(TS_NAME,'w','#'),'s','w'),'t','s'),'#','t')
--
--
--    02.799 e 2.799%
--    07.294 i 7.294%
--    07.631 o 7.631%
--    11.682 a 11.682%
--    eioa
--    Replace(Replace(Replace(Replace(Replace(TS_NAME,'e','#'),'i','ew'),'o','i'),'a','o'),'#','a')
--
--    -- dont replace
--    00.222 q 0.222%
--    00.763 y 0.763%
--    01.183 u 1.183%

-- Obfuscate a name
Select
   ts_id,
   Cast(ts_name as varchar(42)) as [Original Name]

   Cast(dbo.fnConvert_TitleCase(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(TS_NAME,'x','#'),'z','x'),'#','z'),'k','#'),'j','k'),'v','j'),'#','v'),'g','#'),'n','g'),'l','n'),'#','l'),'r','#'),'d','r'),'m','d'),'#','m'),'f','#'),'h','f'),'p','h'),'b','p'),'c','b'),'#','c'),'w','#'),'s','w'),'t','s'),'#','t'),'e','#'),'i','ew'),'o','i'),'a','o'),'#','a')) as VarChar(42)) As [morphed name] ,
   Cast(dbo.fnConvert_TitleCase(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(TS_NAME,'e','t'),'~','e'),'t','~'),'a','o'),'~','a'),'o','~'),'i','n'),'~','i'),'n','~'),'s','h'),'~','s'),'h','r'),'r','~'),'d','l'),'~','d'),'l','~'),'m','w'),'~','m'),'w','f'),'f','~'),'g','y'),'~','g'),'y','p'),'p','~'),'b','v'),'~','b'),'v','k'),'k','~'),'x','~'),'j','x'),'~','j')) as VarChar(42)) As [morphed name2]

From
   ts_users
;

2voto

warren Punkte 30258

Eine sehr einfache Lösung wäre, den Text ROT13 zu schreiben.

Eine bessere Frage wäre vielleicht, warum Sie das Bedürfnis haben, die Daten zu verschlüsseln? Wenn Sie einen Verschlüsselungsschlüssel haben, könnten Sie auch erwägen, den Text mit DES oder AES oder ähnlichem zu verschlüsseln. Dies würde jedoch potenzielle Leistungsprobleme mit sich bringen.

2voto

Milan Babuškov Punkte 57324

Wenn ich so etwas mache, schreibe ich normalerweise ein kleines Programm, das zuerst viele Namen und Nachnamen in zwei Arrays lädt und dann einfach die Datenbank mit zufälligen Namen/Nachnamen aus den Arrays aktualisiert. Das funktioniert auch bei sehr großen Datensätzen (200.000+ Datensätze) sehr schnell.

1voto

elifiner Punkte 6849

Ich bin selbst auf das gleiche Problem gestoßen und habe eine alternative Lösung gefunden, die vielleicht auch für andere funktioniert.

Die Idee ist, MD5 auf den Namen anzuwenden und dann die letzten 3 Hexadezimalziffern zu nehmen, um sie in eine Namenstabelle zu übertragen. Sie können dies getrennt für Vor- und Nachname tun.

3 Hexadezimalziffern stehen für Dezimalzahlen von 0 bis 4095. Wir brauchen also eine Liste mit 4096 Vornamen und 4096 Nachnamen.

Also conv(substr(md5(first_name), 3),16,10) (in MySQL Syntax) wäre ein Index von 0 bis 4095, der mit einer Tabelle verbunden werden könnte, die 4096 Vornamen enthält. Das gleiche Konzept könnte auf Nachnamen angewendet werden.

Die Verwendung von MD5 (im Gegensatz zu einer Zufallszahl) garantiert, dass ein Name in den Originaldaten immer demselben Namen in den Testdaten zugeordnet wird.

Eine Liste der Namen finden Sie hier:

https://gist.github.com/elifiner/cc90fdd387449158829515782936a9a4

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X