1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/perl
use Algorithm::LUHN qw(is_valid);
use autodie; # Automatic errors on file problems.
use strict;
use warnings;
# This is the name of the file we want to modify.
my $filename = 'test_ccc9999.txt';
# We're going to create a temporary file. This avoids us having
# to build up a potentially large string in memory.
my $tempname = $filename . '.tmp';
do
{
# Open both files. Doing this using lexical file handles
# within a "do" block means that when the end of the block
# is reached, the files will be closed.
open my $input_h, '<', $filename; # input handle
open my $output_h, '>', $tempname; # output handle
# Loop through each line of input.
while (my $row = <$input_h>)
{
while ($row =~ /(3[47]\d{13})/g)
{
if (is_valid("$1")) {
print "$1\n";
$1 =~ s/(3[47]\d{9})(\d{4})/XXXXXXXXXXX$2/g;
}
#print "$1\n";
}
# Write it out.
print $output_h $_;
}
};
# Delete the original file.
unlink $filename while -f $filename;
# Rename the temporary file to the original filename.
rename $tempname => $filename;
2015-02-17T15:19:54 marcus74Code: (dl )$1 =~ s/(3[47]\d{9})(\d{4})/XXXXXXXXXXX$2/g;
Quoteist lustig... Solange löschen, bis die Datei auch wirklich weg ist?unlink $filename while -f $filename;
QuoteHallo Raubtier,
danke für deinen Hinweis, zumindest wird im 2.Schleifendurchlauf jetzt die "echte" CC maskiert aber hat du noch eine Idee wie ich die Daten wieder zurück ins File bekommen, bei gleicher Originalstruktur ?
Derzeit bekomme ich die Fehlermeldung:
QuoteUse of uninitialized value $_ in print at cc3a.pl line 41, <$_[...]> line 1533.
Danke !
Gruß
Marcus
2015-02-17T16:15:15 betterworldÜbrigens solltest du auch Fehler beim Öffnen der Dateien behandeln:
QuoteCode (perl): (dl )unlink $filename while -f $filename;
1 2 3 4
my ($creditcard) = $row =~ /(3[47]\d{13})/ or next; # In der nächsten Zeile weitermachen if (is_valid($creditcard)) {...}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
my %found; # c sagt: mache nach dem letzten match weiter (continue after last match) # Das problem ist nur das jede andere regex den counter für diese zurücksetzt # also bedarf es eine prüfung die ohne regex auskommt, # falls ein wert keine keditkartennummer ist, # damit die schleife nicht hängen bleibt while ($row =~ /(3[47]\d{13})/gc) { # Werte zwischenspeichern, Da jede regexp $1 usw. überschreibt. my $number=$1; # also wert speichern und überspringen wenn schon gefunden next if($found{$number}++); # weiter wenn es nicht passt # hier kann es passieren das die regex-engine zurück gesetzt wird # zb durch eine andere regex next unless(is_valid($number)); print "$number\n"; # nun den gefundenen wert mit dem maskierten ersetzen my $masked=$number; # achtung! das setzt die regex-engine zurück! $masked=~s/^.+(\d{4})$/XXXXXXXXXXX$1/; $row=~s/$number/$masked/g; # hiernach beginnt die regex im while wieder am anfang der zeile, # was aber unproblematisch ist, # da alle entweder die werte maskiert wurden, # oder in "%found" stehen. }