Home > Enterprise >  Trying to hash all strings in the file after the comma separator
Trying to hash all strings in the file after the comma separator

Time:10-27

I have a file with keywords on each line. The line starts with number then comma and after that the keyword (like comma separated csv but text file). The file looks like this

7,n00t
41,n01
13,n021
21,n02
18,n03
13,n04
15,n05
13,n06
18,n07
13,n08
14,n09
9,n0a

What I'm trying is to run whole file and hash only the keywords without the number before the comma.

What I'm tried is this.

   $savePath = "test-file.txt";

    $handle = fopen($savePath, "r ");

    if ($handle) {
        while (($line = fgets($handle)) !== false) {

            $hash1 = substr($line, strpos($line, ",")   1); 
            $hash2 = hash('ripemd160', $hash1);
            fwrite($handle, $hash2);
        }
        fclose($handle); 
    } else {
        echo "Can't open the file!";
    } 

It is working but the problem is that it is hashing the number before the comma and on most of the lines I get one string. This is the output

d743dcc66de14a3430d806aad64a67345fd0b23d0007
75f32ebf42e3ffd70fc3f63d3a61fc6af0075c24000088
7b816ac9cbe2da6a6643538564216e441f55fe9f6,00009
f0ba52b83ffac69fddd8786d6f48e7700562f0170b
def75b09e253faea412f67e67a535595b00366dce
c0da025038ed83c687ddc430da9846ecb97f3998l
c0da025038ed83c687ddc430da9846ecb97f39985,0000r
c12530b4b78bde7bc000e4f15a15bcea013eaf8c
9c1185a5c5e9fc54612808977ee8f548b2258d31,00010
efa60a26277fde0514aec5b51f560a4ba25be3c111
0e25f9d48d432ff5256e6da30ab644d1ca726cb700123
ad6d049d794146aca7a169fd6cb3086954bf2c63012

Should be

7,d743dcc66de14a3430d806aad64a67345fd0b23d0007
41,75f32ebf42e3ffd70fc3f63d3a61fc6af0075c24000088
13,7b816ac9cbe2da6a6643538564216e441f55fe9f6,00009
21,f0ba52b83ffac69fddd8786d6f48e7700562f0170b
18,def75b09e253faea412f67e67a535595b00366dce
13,c0da025038ed83c687ddc430da9846ecb97f3998l
15,c0da025038ed83c687ddc430da9846ecb97f39985,0000r
13,c12530b4b78bde7bc000e4f15a15bcea013eaf8c
18,9c1185a5c5e9fc54612808977ee8f548b2258d31,00010
13,efa60a26277fde0514aec5b51f560a4ba25be3c111
14,0e25f9d48d432ff5256e6da30ab644d1ca726cb700123
9,ad6d049d794146aca7a169fd6cb3086954bf2c63012

Any ideas what is the problem?

CodePudding user response:

The thing is you are reading and writing to the file at the same time. This way, internal pointer is being juggled all the time. Instead, read all the lines, store the result in an array and fseek the file pointer to the beginning of the file again and keep writing the new lines one by one as shown below.

Snippet:

<?php

$handle = fopen("test-file.txt", "r ");

if (!$handle) {
  throw new Exception("Can't open file!");
}

$newLines = [];

while (($line = fgets($handle)) !== false) {
    $hash = hash('ripemd160', substr($line, strpos($line, ",")   1));
    $newLines[] = substr($line, 0, strpos($line, ",")) . "," . $hash;
}

fseek($handle, 0);

foreach($newLines as $line){
  fwrite($handle, $line . "\n");
}

fclose($handle);

CodePudding user response:

The trouble is twofold:

  1. You're trying to write to the file you're reading, while you're reading it without even changing the position of the file pointer, and vice-versa for the reads.
  2. You're trying to overwrite 3-4 bytes of data with 32 bytes of data, which ends up clobbering most of the rest of the input you're trying to read.

If you want to change a file like this you need to create a new file, write your data to that, and then rename the new file to the old one.

Also, use fgetcsv() and fputcsv() to read and write CSV files, otherwise you're going to wind up fighting with edge cases when your input data starts getting complex.

$savePath = "test-file.txt";

$in_h = fopen($savePath, "r ");
$out_h = fopen($savePath.'.new', 'r ');

if ($in_h) {
    while (($line = fgetcsv($in_h)) !== false) {
        $line[1] = hash('ripemd160', $line[1]);
        fputcsv($out_h, $line);
    }
    fclose($in_h);
    fclose($out_h);
    rename($savePath.'.new', $savePath);
} else {
    echo "Can't open the file!";
}
  •  Tags:  
  • php
  • Related