[SOLVED] Get strings distributed along up to 3 lines
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Thank you. This time it seems to work the if condition and handles it the "9A" too.
I know which fruits to get, but I don't know all the "9X" that could appear in binary,
so, If this is not too complicated, for those values that are not defined in fruit array,
could be printed the value found for example, if I don't have defined "9C" in fruit array
and that value is found, print "fruit_9C". This could help me to enrich each time the code
to consider all cases.
Hello grail,
I've modified to
Code:
File.open(ARGV[0], "rb")
but I get the same error
Code:
$ ruby script.rb binary
script.rb:15:in `gets': encoding mismatch: UTF-8 IO with ASCII-8BIT RS (ArgumentError)
from script.rb:15:in `gets'
from script.rb:15:in `<main>'
binary.txt is the binary file, I only put that extension to be able to upload the file to forum, because
without extension is not allowed.
while ( defined $y[$x] ) {
if ( ! defined $fruit[hex($y[$x])] ) {
print "Error: fruit for $y[$x] is missing\n";
$x += 8;
next;
}
printf(" %s %d|%d|%s|%d",$fruit[hex($y[$x])],hex($y[$x+3]),hex($y[$x+4]),$y[$x+5],hex($y[$x+6]));
printf("|%d",hex($y[$x+7])) if defined $y[$x+7];
$x += 8;
}
be care, not tested, probably does not work
Also you can modify the text printed....
From what I can find this is an issue with 1.9.3 not handling things quite as smooth as 2.0, hence I receive no errors with or without the change and running it in all the ways you have tried.
Try removing the 'r' and see if that helps:
Code:
File.open(ARGV[0], "b")
Sorry to mess you around a bit but this is a new to me as far as I never tried to open a binary file in a previous version of ruby
Just saw pan64's post and as another option you could also maybe add to the array a default like 'NO_FRUIT' at that point in the array:
Code:
while ( defined $y[$x] ) {
$fruit[hex($y[$x])] = "NO_FRUIT" if ( ! defined $fruit[hex($y[$x])] );
printf(" %s %d|%d|%s|%d",$fruit[hex($y[$x])],hex($y[$x+3]),hex($y[$x+4]),$y[$x+5],hex($y[$x+6]));
printf("|%d",hex($y[$x+7])) if defined $y[$x+7];
$x += 8;
}
I am sure pan64 will correct me if I have used the incorrect variable syntax
I am sure pan64 will correct me if I have used the incorrect variable syntax
perl -c <script> will do that for you.
Otherwise, yes, it should work and also we can print error message to stderr instead of stdout
(using $fruit[hex($y[$x])] several times will degrade performance)
my $SEP = $ARGV[1];
$/ = "\xff" . chr(oct("0x$SEP"));
have you measured the execution times?
Hello pan64,
Thank you. I've had an internet connection issue to answer before. Yes, I've tested both scripts.
Hello grail and pan64,
I just must to say that both are great scripts!
I've tested both scripts with an input binary of 2GB.
Code:
- Using Ruby script, the output takes 00:08:16 minutes
- Using Perl script, the output takes 00:04:08 minutes
pan64,
With Perl one issue, it runs up to the end and it seems to print all, but during the
execution are printed the following lines and I don't understand the error and I don't know how to fix it:
Code:
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 1097738.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 1635529.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 1721239.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 3081257.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 3310170.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 4195601.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 4782198.
Hexadecimal number > 0xffffffff non-portable at ./Script.pl line 29, <F> chunk 4834811.
Line 29 is this:
Code:
printf("%d %s|%s",hex($a),$b,$c);
grail,
The Ruby script was only printing up to line 7, due to an hex to decimal convertion, the error was:
Code:
`printf': invalid value for Integer(): "0000008" (ArgumentError)
use Math::BigInt; # at the beginning of the script
printf("%s %s|%s",Math::BigInt->new("0x$a"), $b, $c);
# (not tested)
but it will definitely slow down the execution. If those printed lines were acceptable I would ignore these warnings.
no warnings 'portable'; # Support for 64-bit ints required
The Ruby script was only printing up to line 7, due to an hex to decimal convertion, the error was:
Just to clarify, as the start of the strings we are looking at are 0's followed by a number, Ruby has interpreted it as Octal.
If number is to be an int then the following is more correct:
Code:
printf("%d %s %s",$1.to_i,$2,$3)
If it is in fact supposed to be hex then you can process as you have or:
Code:
printf("%d %s %s",$1.to_i(16),$2,$3)
Below are changes for an array version of fruits to see if that runs quicker as suggested by pan64:
Code:
# add the below and remove hash
BEGIN{ $/="\xff\x77"
fruit = [] }
fruit[0] = "APPLE"
fruit[1] = "LIME"
fruit[2] = "ORANGE"
fruit[3] = "GRAPE"
fruit[6] = "PEAR"
fruit[7] = "CHERRY"
# and change the following
printf(" %s ",fruit[y[0]])
# to
printf(" %s ",fruit[y[0].to_i(16)])
I've tested with "Math::BigInt;". It works, this time don't print the errors, but you're rigth, the execution time increases
from 00:04:08 minutes to 00:07:11 minutes. As you said maybe those warnings could be ignored only.
Hello grail,
I've tried to use the array in the way you said me, but doesn't print the associated values like APPLE, LIME, etc and if the array contains non-numerical values (something similar as what happened before with perl script), i.g., if I put the fruit["9A"]="MELON" I get this error:
Code:
Script.rb:20:in `[]=': no implicit conversion of String into Integer (TypeError)
from Script.rb:20:in `<main>'
and line 20 contains this:
Code:
fruit["9A"] = "MELON"
And I was not able to test your Ruby script under Windows using IRB, because even when in Ubuntu and IRB has
Ruby 2.0.0, in Windows I'm getting this error:
Code:
C:\Scripts>ruby script.rb binaryfile
script.rb:18:in `gets': encoding mismatch: CP850 IO with UTF-8 RS
(ArgumentError)
from script.rb:18:in `gets'
from script.rb:18:in `<main>'
You will not be able to run in irb as it would need to be altered to be a module to be loaded and then executed.
As for the array setup, you would need to perform the same conversion as in the Perl script, but remembering that it only uses the individual character, ie instead of 91 it is just 1,
so instead of 9a it would be just a.
With the above information in hand, to add the letter portions to the array simply use:
Code:
fruit["a".hex] = "MELON"
And to overcome the issue of not having a corresponding entry in the array, make the following change:
Code:
fruit[y[0]] = "MISSING" if fruit[y[0]].nil?
printf(" %s ",fruit[y[0]])
I don't receive anymore the "no implicit convertion error", but even when I've added the line
Code:
fruit["a".hex] = "MELON"
is not printing "MELON" in the output. I'm receiving
this output using the file I've attached in previous post called binary1.txt even when contains the string "9A":
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.