I am parsing an html documents, and there is a variable var key = 0xa9 for example, i do use my regex and all, but the 0xa9 i am getting is stored in a variable as a string, is there any cast function or anything to convert it to a number?
EDIT :
I am sure i didn't explain myself well, this is what i have been trying to do :
$t = $t . chr ( ord(substr($e, $i, 1)) ^ $var); BUT $var = "0xa9" or whatever, the thing is it is a string, so in the previous operation i do get an error Argument "0xc2" isn't numeric in bitwise xor (^) at, that is why i want the exact same value but not as a string, in order to work, $var needs to be like $var = 0xa9 for example.
Try
print hex '0xAf'; # prints '175'
From perldoc
hex
Interprets EXPR as a hex string and returns the corresponding value.
(To convert strings that might start with either 0 , 0x , or 0b, see oct.)
If EXPR is omitted, uses $_ .
Please try this:
print hex $string
Try adding 0x0 to $var. It should convert the second operand in XOR operation to numeric value.
$t = $t . chr ( ord(substr($e, $i, 1)) ^ ($var + 0x0));
Related
I have an old legacy system that is pulling postgres bytea data from a database (can't change the code as it's compiled). How do I go about converting bytea data that is in this format to an ascii string?
Here is a sample of the data:
my($value) = "\x46726f6d3a20224d";
I found this example online to decode a hex string, but the input has to start with 0x, not \x. If I change the test string from \x to 0x then this example works however the \x is treating the next HEX 46 as a capital F as it's doing the regex match, then the rest is failing to decode.
Here is the regex I had found that works with a string starting with 0x but not \x, Is it possible to decode this type of hex string somehow?
$value =~ s/0x(([0-9a-f][0-9a-f])+)/pack('H*', $1)/ie;
print $value, "\n";
Correct output when you use 0x on the input string:
From: "M
Incorrect output (not decoded) when using \x on the input string:
F726f6d3a20224d
Cheers, Mike
Assuming you actually have the string
\x46726f6d3a20224d
as produced by
my $value = "\\x46726f6d3a20224d";
Then all you just need to replace the 0 with \\.
$value =~ s/\\x(([0-9a-f][0-9a-f])+)/pack('H*', $1)/ie;
Better (less repetition and it avoids slowdowns related to ß):
$value =~ s/\\x((?:[0-9a-fA-F]{2})+)/ pack( 'H*', $1 ) /e;
If you expect this to be the whole string, then I'd use
$value = pack( 'H*', $value =~ s/^\\x//r );
The following is faster, but loses some validation:
$value = pack( 'H*', substr( $value, 2 ) );
$temp = 'abc'.0x12;
print $temp; # prints abc18
While appending the hex value to string it is getting converted to decimal value and final result is string. what I want is that the ascii value of the hex should get appended to the string.
for e.g. 0x12 in ascii is DC2 (device control 2).
Try using chr:
my $a = 'abc'.chr 0x3e;
print $a;
I think Sly Raskal was on the right track but instead of %x use %c, so:
my $hex = 0x12;
my $ascii = sprintf "%c", $hex;
my $temp = 'abc' . $ascii;
I think this gives the result you were looking for. I got it from http://www.perlmonks.org/?node_id=191039 .
Has something changed in Perl or has it always been this way, that examples like the second ($number eq 'a') don't throw a warning?
#!/usr/bin/env perl
use warnings;
use 5.12.0;
my $string = 'l';
if ($string == 0) {};
my $number = 1;
if ($number eq 'a') {};
# Argument "l" isn't numeric in numeric eq (==) at ./perl.pl line 6.
Perl will be try to convert a scalar to the type required by the context where it is used.
There is a valid conversion from any scalar type to a string, so this is always done silently.
Conversion to a number is also done silently if the string passes a looks_like_number test (accessible through Scalar::Util). Otherwise a warning is raised and a 'best guess' approximation is done anyway.
my $string = '9';
if ( $string == 9 ) { print "YES" };
Converts the string silently to integer 9, the test succeeds and YES is printed.
my $string = '9,8';
if ( $string == 9 ) { print "YES" };
Raises the warning Argument "9,8" isn't numeric in numeric eq (==), converts the string to integer 9, the test succeeds and YES is printed.
To my knowledge it has always been this way, at least since v5.0.
It has been that way.
In the first if, l is considered to be in numeric context. However, l cannot be converted to a number. Therefore, a warning is emitted.
In the second if, the number 1 is considered to be in string context. Therefore the number 1 is converted to the string '1' before comparison and hence no warnings are emitted.
Did you use a lowercase "L" on purpose? It's often hard to tell the difference between a lowercase "L" and one. You would have answered your own question if you had used a one instead.
>perl -wE"say '1' == 0;"
>perl -wE"say 1 eq 'a';"
>
As you can see,
If one needs a number, Perl will convert a string to a number without warning.
If one needs a string, Perl will convert a number to a string without warning.
Very consistent.
You get a warning when you try to convert a lowercase L to a number, but how is that surprising?
What is the Perl equivalent of strlen()?
length($string)
perldoc -f length
length EXPR
length Returns the length in characters of the value of EXPR. If EXPR is
omitted, returns length of $_. Note that this cannot be used on an
entire array or hash to find out how many elements these have. For
that, use "scalar #array" and "scalar keys %hash" respectively.
Note the characters: if the EXPR is in Unicode, you will get the num-
ber of characters, not the number of bytes. To get the length in
bytes, use "do { use bytes; length(EXPR) }", see bytes.
Although 'length()' is the correct answer that should be used in any sane code, Abigail's length horror should be mentioned, if only for the sake of Perl lore.
Basically, the trick consists of using the return value of the catch-all transliteration operator:
print "foo" =~ y===c; # prints 3
y///c replaces all characters with themselves (thanks to the complement option 'c'), and returns the number of character replaced (so, effectively, the length of the string).
length($string)
The length() function:
$string ='String Name';
$size=length($string);
You shouldn't use this, since length($string) is simpler and more readable, but I came across some of these while looking through code and was confused, so in case anyone else does, these also get the length of a string:
my $length = map $_, $str =~ /(.)/gs;
my $length = () = $str =~ /(.)/gs;
my $length = split '', $str;
The first two work by using the global flag to match each character in the string, then using the returned list of matches in a scalar context to get the number of characters. The third works similarly by splitting on each character instead of regex-matching and using the resulting list in scalar context
How can I convert the binary string $x_bin="0001001100101" to its numeric value $x_num=613 in Perl?
My preferred way is:
$x_num = oct("0b" . $x_bin);
Quoting from man perlfunc:
oct EXPR
oct Interprets EXPR as an octal string and returns the
corresponding value. (If EXPR happens to start
off with "0x", interprets it as a hex string. If
EXPR starts off with "0b", it is interpreted as a
binary string. Leading whitespace is ignored in
all three cases.)
sub bin2dec {
return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
As usual, there's is also an excellent CPAN module that should be mentioned here: Bit::Vector.
The transformation would look something like this:
use Bit::Vector;
my $v = Bit::Vector->new_Bin( 32, '0001001100101' );
print "hex: ", $v->to_Hex(), "\n";
print "dec: ", $v->to_Dec(), "\n";
The binary strings can be of almost any length and you can do other neat stuff like bit-shifting, etc.
Actually you can just stick '0b' on the front and it's treated as a binary number.
perl -le 'print 0b101'
5
But this only works for a bareword.
You can use the eval() method to work around the bare-word restriction:
eval "\$num=0b$str;";