EVOLUTION-MANAGER
Edit File: Ephemeral.pm
#!/usr/bin/perl package Razor2::Signature::Ephemeral; use strict; use Data::Dumper; BEGIN { eval { require Digest::SHA; import Digest::SHA qw(sha1_hex); 1 } or do { require Digest::SHA1; import Digest::SHA1 qw(sha1_hex) } } sub new { my ($class, %args) = @_; my $self = bless { seed => $args{seed} || 42, separator => encode_separator($args{separator}) || encode_separator("10"), }, $class; $self; } sub hexdigest { my ($self, $content) = @_; # Initialize PRNG with $seed srand($$self{seed}); my @content = split /$$self{separator}/, $content; # $content =~ s/$$self{separator}//g; -- We don't do this anyore # my $size = length($content); my $lines = scalar @content; debug("\nNumber of lines: $lines"); # Randomly choose relative locations and section sizes (in percent) my $sections = 6; my $ssize = 100/$sections; my @rel_lineno = map { rand($ssize) + ($_*$ssize) } 0 .. ($sections-1); my @lineno = map { int(($_ * $lines)/100) } @rel_lineno; debug("Relative Line Numbers (in percent): @rel_lineno"); debug("Absolute Line Numbers: @lineno"); my @rel_offset1 = map { rand(50) + ($_*50) } qw(0 1); my @rel_offset2 = map { rand(50) + ($_*50) } qw(0 1); debug("Relative Offsets for section 1: @rel_offset1"); debug("Relative Offsets for section 2: @rel_offset2"); my ($l1, $l2) = (0, 0); for ($lineno[1] .. $lineno[2]) { $l1 += length($content[$_]) if $content[$_]} for ($lineno[3] .. $lineno[4]) { $l2 += length($content[$_]) if $content[$_] } debug("Length of the first section: $l1 bytes"); debug("Length of the second section: $l2 bytes"); my @offset1 = map { int(($_ * $l1)/100) } @rel_offset1; my @offset2 = map { int(($_ * $l2)/100) } @rel_offset2; debug("Chunk start/end positions in Section 1: @offset1 (length: " . ($offset1[1] - $offset1[0]) .") "); debug("Chunk start/end positions in Section 2: @offset2 (length: " . ($offset2[1] - $offset2[0]) .") "); my $x = 0; my ($sc, $sl, $ec, $el) = (0,0,0,0); my $section1 = picksection( \@content, $lineno[1], $lineno[2], $offset1[0], $offset1[1] ); my $section2 = picksection( \@content, $lineno[3], $lineno[4], $offset2[0], $offset2[1] ); debug("Section 1: $section1"); debug("Section 2: $section2"); my $seclength = length($section1.$section2); debug("Total length of stuff that will be hashed: $seclength"); if ($section1 =~ /^\s+$/ && $section2 =~ /^\s+$/) { debug("Both sections were whitespace only!"); $section1 = ""; $section2 = ""; } my $digest; if ($seclength > 128) { $digest = sha1_hex($section1, $section2); } else { debug("Sections too small... reverting back to orginal content."); $digest = sha1_hex($content); } debug("Computed e-hash is $digest"); return $digest; } sub picksection { my ($content, $sline, $eline, $soffset, $eoffset) = @_; my $x = 0; my ($sc, $sl, $ec, $el) = (0,0,0,0); for ($sline .. $eline) { next unless $content->[$_]; $x = $x + length($content->[$_]); if (($x > $soffset) && ($sc == 0)) { # we come here first time $sc = length($content->[$_]) - ($x - $soffset); # $x is greater than start $sl = $_; # offset } if ($x > $eoffset) { $ec = length($content->[$_]) - ($x - $eoffset); $el = $_; } last if $ec; } $sc = 0 if $sc < 0; $ec = 0 if $ec < 0; # FIX! not verified to work correctly. debug("Absolute chunk offsets: Line $sl charachter $sc to line $el character $ec"); my $section = ""; if ($sl == $el) { if ($content->[$sl]) { $section = substr ($content->[$sl], $sc, $ec - $sc + 1); } else { $section = ""; } } else { $section .= substr($content->[$sl], $sc); for ($sl+1 .. $el-1) { $section .= $content->[$_]; } $section .= substr($content->[$el], 0, $ec); } return $section; } sub encode_separator { my ($self, $separator) = @_; my $rv; unless (ref $self) { $separator = $self } my @chars = split/-/, $separator; push @chars, $separator unless scalar @chars; for (@chars) { $rv .= chr($_) } return $rv; } sub debug { my $message = shift; # print "debug: $message\n"; #open TMP, ">>/tmp/ehash"; #print TMP "$message\n"; #close TMP; } 1;