md5 "%02x" fprintf - hash

I have to calculate md5 hash for a file. I succesfully find libraries to do it, and they print the hash on screen.
I have to print the hash on a txt file, but I have some problems. It only prints 00 intead of the all 32 bit hash. This is the print function. I only add the lines to open the file and to print on it, the rest of the function is from the library and works fine, because on the screen the hash is printed in the right way.
Seems to be some kind of problems with fprintf and %02x". Thanks.
static void MDPrint (mdContext)
MD5_CTX *mdContext;
{
int i;
FILE *fp;
if((fp=fopen("userDatabase.txt", "ab"))==NULL) printf("Error while opening the file..\n");
else {
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
}
fclose(fp);
}

Your problem is here;
for (i = 0; i < 16; i++)
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
Since there are no curly braces, only the printf line will be inside the loop. You need to add braces to make both lines be inside the loop;
for (i = 0; i < 16; i++)
{
printf ("%02x", mdContext->digest[i]);
fprintf(fp, "%02x", mdContext->digest[i]);
}

Related

Wrong data is written to binary file [duplicate]

I'm using a large array of floats. After a lot of fiddling I've managed to write it to a binary file. When opening that file at a later time, the reading process only reads a couple of handfuls of floats (according to the return-value of fread(), and it's all values 0.0f). The reading is supposed to put the floats into an (the original) array, and it does not contain the original values.
I'm using Code::Blocks and MinGW doing a program in the 32bit realm on a 64bit pc .. and I'm not very proficient on c/c++ and pointers.
#include<...>
const int mSIZE = 6000 ;
static float data[mSIZE*mSIZE] ;
void myUseFunc(){
const char *chN = "J:/path/flt_632_55.bin" ;
FILE *outFile=NULL ;
# .. sucessfully filling and using data[]
..
size_t st = mSIZE*mSIZE ;
outFile = fopen( chN , "w" ) ;
if(!outFile){ printf("error opening file %s \n", chN); exit(0);}
else{
size_t indt;
indt = fwrite( data , sizeof(float), st , outFile );
std::cout << "floats written to file: " << indt << std::endl ;
#.. value shows that all values ar written
# and a properly sized file has appeared at the proper place
}
fclose( outFile ) ;
}
void myLoadFunc( const char *fileName){
FILE *inFile = NULL ;
inFile = fopen( fileName, "r");
if(!inFile){ printf("error opening file %s \n", fileName); exit(0); }
size_t blok = mSIZE*mSIZE ;
size_t out;
out = fread( dataOne, sizeof(GLfloat), blok , inFile);
fclose(inFile);
if(out != blok){
std::cout<< out << std::endl ;
fputs ("Reading error",stderr);
# no stderr presented at the console ..
printf("some error\n") ;
exit(0);
# .. program exits at out=14
}
...
}
int main( ){
...
const char *FileName = "J:/path/flt_632_55.bin" ;
myLoadFunc( FileName ) ;
...
}
You are not writing to/reading from a binary file, you open the files as text files.
You need to add the "b" to the open mode, like
outFile = fopen( chN , "wb" ) ;

Progress line in perl

I would like to create a very simple progressbar for my script. So far I've got this, and it works. However, I cannot get it to be a percentage out of 100. My code is the following and it produces basically a dot for every 5 entries in #entries.
my $total_entries = #entries;
my $count = 0;
my $count_tens = $total_entries/0.2;
$count_tens = sprintf ('%d',$count_tens);
foreach (#entries){
# do some stuff #
for (1 .. $total_entries){
if ($count == $count_tens){
print ".";
$count = 0;
}
$count++;
}
}
I would like to have something that produces always a fixed amount of dots, regardless of the total number of entries in #entries.
Let's say we want 80 dots. Then:
my $number_of_dots = 80;
my #items = 0 .. 20; # or something
my $items_per_dot = #items / $number_of_dots;
STDOUT->autoflush(1); # print everything out immediately
for my $i (0 .. $#items) {
my $dots = $i / $items_per_dot;
print "\r", "." x $dots;
sleep 1; # do something
}
print "\n";
Note that we avoid rounding errors by calculating the number of dots per item anew on each iteration. The \r will move the cursor to the start of the line, so the existing dots will be overwritten each time. You can easily skip the printing if the $dots value doesn't change between iterations.
Rather than rewriting the wheel, you may want to use existing code that has already been written, tested and debugged.
http://metacpan.org/pod/Term::ProgressBar

Perl for-loop not working as expected

I've been teaching myself Perl for the past couple weeks. For practice, I've been going through problems over at projecteuler.net. I've got a pair of nested for-loops that aren't working as expected. For context, the problem is to find the largest palindromic number that is the product of two 3-digit numbers. Here's my code:
sub isPalindrome($)
{
return 0 if length($_[0]) <= 1;
$reverse = reverse $_[0];
$_[0] == $reverse ? return 1 : return 0;
}
sub findPalindrome{
for($i = 999; $i >= 100; $i--)
{
for($j = 999; $j >= 100; $j--)
{
print "$i\t$j\n";
return ($i, $j, $j * $i) if(isPalindrome($j * $i)); #return the two factors followed by their product#
}
}
}
($factor1, $factor2, $product) = findPalindrome();
print "$factor1 * $factor2 = $product\n";
My problem is that sub findPalindrome is not working as expected. I'm find a palindromic number, but not the highest; it's like it's skipping something in the loop. To try and track down the problem, I inserted the line of code above to make it print out each pair of numbers it iterates through, and it looks like it's iterating properly. My guess is that for-loops in Perl work differently than I'm used to in C++; either way, I'm lost. What am I missing?
Edit: The answer I'm getting is "995 * 583 = 580085", which is indeed a palindromic number, and the multiplication is correct, but it's the wrong answer according to Project Euler. On a whim, I changed the for loops in sub findPalindrome to iterate through 999 to 900, and that gave me the correct answer ("993 * 913 = 906609"). For some reason, when the bottom of the range is 100, it fails to find the answer; when the bottom of the range is 900, it does find it.
I finally read the problem description on top of your question ;) Your loop is not iterating in the desired order. For example 998*998 is encountered after 999*100.

Convert the C Function to Perl

I am stuck while trying to convert the C function convertCNGFileToJPGFile mentioned in the program cng2jpg.c
I have been trying to write the same in Perl but don't have enough knowhow with hex,pack and unpack functions.
Would really appreciate if somebody can write a similar code in Perl as mentioned below.
while ((bytesRead = fread(buffer, 1, kBufferSize, inputFile))) {
if (!isValidCNG) {
if (bytesRead < 11 || strncmp("\xa5\xa9\xa6\xa9", (char *)(buffer + 6), 4)) {
fprintf(stderr, "%s does not appear to be a valid CNG file\n", inputFileName);
return 0;
}
isValidCNG = 1;
}
for (size_t i = 0; i < bytesRead; i++)
buffer[i] ^= 0xEF;
size_t bytesWritten = fwrite(buffer, 1, bytesRead, outputFile);
if (bytesWritten < bytesRead) {
fprintf(stderr, "Error writing %s\n", outputFileName);
return 0;
}
}
Thanks in advance.
If I'm reading the code right, all it's doing (besides the validity check) is XORing each byte in the file with the byte 0xEF (i.e. flipping all but the fifth lowest bit of each byte). In Perl, you could implement that with:
local $/ = \(2**16); # ignore line breaks, read in 64 kiB chunks
while (<>) {
$_ ^= "\xEF" x length;
print;
}
The validity check is just checking that the output is actually a valid JPEG file — specifically, that the 7th to 10th bytes of the output file contain the magic word "JFIF" (which becomes "\xa5\xa9\xa6\xa9" when XORed with 0xEF). Generally, unless you're expecting to frequently run this code on files which are not actually CNG files, I wouldn't bother with it, since it's easier to just check the validity of the output afterwards. (Besides, the check will fail if the decoded file is actually an Exif JPEG image, which have the magic word "Exif" instead.)
If you do want to include the check, something like this should do it:
local $/ = \(2**16); # ignore line breaks, read in 64 kiB chunks
while (<>) {
$_ ^= "\xEF" x length;
die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;
print;
}
Ps. If this code runs too slow, I'd suggest two possible improvements: 1) use a larger buffer, and b) preallocate the mask of 0xEF bytes instead of rebuilding it on the fly each time:
local $/ = \(2**20); # ignore line breaks, read in 1 MiB chunks
my $mask = "\xEF" x $$/;
while (<>) {
$_ ^= substr($mask, 0, length);
die "Not a valid CNG file" if $. == 1 and not /^.{6}(JFIF|Exif)/s;
print;
}

How can I update values on the screen without clearing it in Perl?

I want to display a set of values on screen and update that value every 5 seconds. I don't want to clear the screen.
eg:
hours: 1
mins : 30
sec: 45
here, values should change accordingly.
How should i do that in Perl?
Regards,
Anandan
Are you talking about getting more control over where things are printed on your screen? Then you probably want to check out the Term::Cap module.
A poor man's way to do this on one line is to use \r to keep overwriting the same line.
while ($t>0) {
# note no new line at the end of printf statement
printf "\rHours: %d Minutes: %d Seconds: %d ", $t/3600, ($t/60)%60, $t/60;
sleep 5;
$t -= 5;
}
EDIT Here's something that works on my system. Your terminal's capabilities may vary.
require Term::Cap;
$terminal = Tgetent Term::Cap { TERM => cygwin, OSPEED => 9600 };
$terminal->Trequire("up"); # move cursor up
$UP = $terminal->Tputs("up");
$t = 500;
while ($t > 0) {
printf "Hour: %d \n", $t/3600;
printf "Minute: %d \n", ($t/60)%60;
printf "Second: %d \n", $t%60;
print $UP,$UP,$UP;
sleep 5;
$t -= 5;
}
For this sort of thing I like to use Curses. It's just not for Perl, either. :)
Something like this:
use Term::ANSIScreen qw(cls);
while(1) {
cls;
print "....";
sleep 5;
}
Alternatives of "cls" can be found in this question.