- Prison Code Breaker Diary -

=> aka: Nhật Kí Code Tù

Categories

Showing posts with label Perl. Show all posts

These functions are usually used when dealing with binary data: open, read, write, close, seek and binmode.

I've written this perl script to generate a random binary file:

#!/bin/perl -w

use strict;

use constant RANGE => 0xFF;

if( $#ARGV != 1 ) {
    print "Error: no argument input!\n";
    print "Usage: > perl $0 FILE_NAME MAX_BYTES\n";
    print "Example: > perl $0 data.bin 255\n";
    exit;
}

my $file = $ARGV[0];
my $max_bytes = $ARGV[1];

my $cnt = 0;

open FILE,">", $file or die $!;

while( $cnt < $max_bytes ) {
    print FILE chr(int(rand(RANGE)));
    ++$cnt;
}

close FILE;

print "Binary file '$file' ($max_bytes bytes) generated!\n";

binmode() is not in used, so how does it work? Because I generate random value in ASCII so I can easily convert it into its according character, then simply write into file. It does sound weird but it actually works! The case of using binmode() and just print the number, it doesn't write the binary as expected. I don't understand why ???? The next script is to read a binary file and print out the hex code of each character inside.
#!/bin/perl -w

use strict;

if( @ARGV != 2 ) {
    print
     "Error: wrong arguments input!\n",
 "Usage: > perl $0 FILE BYTES\n",
 "Example: > perl $0 data.bin 255\n";
    exit;
}

my $file = $ARGV[0];
my $bytes = $ARGV[1];

open FILE, "<", $file or die $!;
#binmode FILE;

my $cnt = 0;
while( $cnt < $bytes ) {
    read FILE, my $byte, 1;
    print  sprintf("%02X", ord($byte)). " ";
    ++$cnt;
}
close FILE;
print "\n";


I use read() to get each byte then re-format into hex then print().
I don't use binmode() but it still does work well.

So I think I just don't need binmode() even though it's a binary case.

On exponentiation, don't take the number too big like: 10 ** 99999 ... otherwise, u will get unexpected result or 1.#INF

The remainder operator doesn't apply for floating-point number, but if you do then they all will be round-off into the closest integers, then apply the operator.

In Perl, the floating-point number can be written in the form like this: 1E+01, 23.45e-02, 8.567E+32 ...
The letter 'E' or 'e' denotes the exponent.

Here the case:

my $var_1 = 11E+30;
my $var_2 = 11e30;
my $small_number = 0.00001; # or 1e-05

print "First case: $var_1 - $var_2 + $small_number = ".($var_1 - $var_2 + $small_number)."\n";
print "Second case: $var_1 + $small_number - $var_2 = ".($var_1 + $small_number - $var_2)."\n";
Here the result:
First case: 1.1e+031 - 1.1e+031 + 1e-005 = 1e-005
Second case: 1.1e+031 + 1e-005 - 1.1e+031 = 0
So how does it actually work?
I can explain it like this.
At line 5, $var_1 and $var_2 is eliminated down to 0 since they're equal in value, thus, adding a small value will be kept.
At line 6, $var_1 will be adding the $small_number, but because the value is too small compared to the other side, then it is considered as 0; so, the next substract to $var_2 will be 0 in result.

Check another example to see if the value is too small
my $too_small = 1e-999;
print "value is $too_small\n";
The result is 0 certainly, as I explained above.

I'm talking about the conditional statement IF.
Here is the definition:

IF (exp) {
   (statement)
}
Try this example:
$age = 23; 
if ( $age == 23 ) {
   print "I am 23 years-old", '\n'
}
Certainly perl evaluates the expression is TRUE since $age is assigned to the value '23'.
How about this case:
if ( $age = 23 ) {
   print "I am 23 years-old", '\n'
}
Still you've got the result printed. But how do you explain what perl does to this evaluation?

1. First, $age is assigned to value '23'.
2. The expression is evaluted whether it is TRUE or FALSE, which means, $age is ZERO or non-ZERO. So, it's TRUE right here because '23' is definitely not '0'.
3. Statement 'print' is called.

Rewrite the explanation into the code itself:
$age = 23;
if ($age) {
   print "I am 23 years-old", '\n'
} 

If u try with constants assignment, u'll get error
if ( 20 = 55 ) {    
    print "is it ok?", '\n'
}

Found = in conditional, should be ==
(W syntax) You said

if ($foo = 123)

when you meant

if ($foo == 123)

(or something like that).

Can't modify constant item in scalar assignment
A fatal error (trappable)
You aren't allowed to assign to the item indicated, or otherwise try
to change it, such as with an auto-increment.

Same results but different operators mean differences.

I'm mentioning about the '=' and the '==' operators with different means, applied to all logical cases.

use constant
HACK
#???
=> 1
;($p, $h)
=
split ( ' ',
chr(112). "E". join('',

('T' . chr(0144) ) ) .chr(0x20) .
# <<END>>
join('', ('QmOt' , 'S'.###*&#^$(&
'uoH' ) )
#(*$)) WHAT THE HELL#$-~#msl39$#
)
;
qw [
/ 7h1s i5 5o 4nN0y1nG /
{ 4 rE4L }

]
;++$p;#
$h =
#--fosortc
(reverse $h
);chop($h); xJAPHx:
++$h
; print lc
join ( ' '
, (${\${\${\$p}}}
, ${\$h} )
)
;

Hiện tại mình đang viết cuốn sách hướng dẫn lập trình Perl cơ bản bằng tiếng Việt và chỉ dành cho những ai hiểu được tiếng Việt :D
Tên sách: Perl - The 1st Step (Hướng dẫn lập trình Perl cơ bản)
Tác giả: Pete H.

Download

(2010-Feb-05)[JaPh] Perl - The 1st Step (PDF - 1.12 MB)
(2010-Feb-06)[JaPh] Perl - The 1st Step (PDF - 1.14 MB)
(2010-Feb-07)[JaPh] Perl - The 1st Step (PDF - 1.21 MB)
(2010-Feb-09)[JaPh] Perl - The 1st Step (PDF - 1.40 MB)
# Changelog - Thông tin cập nhật

• 2009-Mar-15: sách bắt đầu được viết.
• 2009-Nov: chỉnh sửa và đính chính lần 1.
• 2010-Feb: hoàn thiện cơ bản nội dung và format kiểu cách sách.
• 2010-Feb-05: xuất bản trên Internet lần đầu tiên.
• 2010-Feb-06:

  1. cập nhật thông tin perl editor và perl ide.
  2. thêm hình minh họa.
  3. cập nhật link download sách và version.
• 2010-Feb-07:
  1. cập nhật thêm hình minh họa.
  2. thêm mục mới: K. Comment trong perl.
  3. thêm mục mới: L. Chỉ thị Perl - SHEBANG.
  4. đính chính một vài lỗi chính tả.
• 2010-Feb-09:

  1. cập nhật thêm vào Mục Lục và Phụ Lục.
  2. thêm mục link download công cụ.
  3. thêm hướng dẫn cài đặt EPIC để lập trình Perl.
  4. sửa một vài lỗi chính tả.
  5. thay đổi theme cho mã nguồn perl.
  6. thay đổi theme cho các đoạn code ghi chú.

Best Regards,

Language: Perl
Presiquisite: XML::Simple

Assuming we have a xml file like this: data.xml

<?xml version="1.0" encoding="UTF-8"?>
<database>
<user>
<uname>Pete Houston</uname>
<upass>123456</upass>
<email>pete.houston.17187@gmail.com</email>
<id>1</id>
</user>
<user>
<uname>Bach Van Kim</uname>
<upass>987654</upass>
<email>bvkvn06@gmail.com</email>
<id>2</id>
</user>
</database>
We will dump this XML tree using XML::Simple and Dumper package:

#!C:\perl\bin\perl.exe -w
use strict;
use XML::Simple;
use Data::Dumper;

print Dumper( XML::Simple->new()->XMLin("data.xml"));

The result shows:

$VAR1 = {
'user' => {
'1' => {
'email' => 'pete.houston.17187@gmail.com',
'uname' => 'Pete Houston',
'upass' => '123456'
},
'2' => {
'email' => 'bvkvn06@gmail.com',
'uname' => 'Bach Van Kim',
'upass' => '987654'
}
}
};

The method: XML::Simple->new() will create an object to handle XML file, and then input file will be called through method XMLin("filename.xml");
A very simple way!

I used to install ActiveState Perl because I thought it's the best Perl distribution on Windows. However, several days ago I've found out that Strawberry Perl is also port to Windows.
After a try, I feel like Strawberry Perl is much more better than ActiveState Perl.
Like what?

- Well, ActiveState Perl is commercial, then you're limited to use only from its vendor repositories. It would be a trouble if you want to install some packages from CPAN to your system. Yes, very limited!
- On the other hand, Strawberry Perl is an open-source, community-developed package, very light and useful, supporting all the most needed package for programmers and developers. Yes, it's free! Additionally, you can access CPAN shell and install any package from CPAN easily. It's quick and convenient in many ways.

Here the instruction on how to install Gtk+ for Perl on Windows.
There are two options:

1. Simply download and setup CamelBox:

2. Using ActivePerl:
+ Download and install ActivePerl: https://www.activestate.com/activeperl/downloads/
+ Download and install Gtk+ Environment for Windows: http://cdnetworks-kr-2.dl.sourceforge.net/project/gladewin32/gtk%2B-win32-runtime/2.8.20/gtk-2.8.20-win32-1.exe
+ Open command and type:


ppm repo add http://www.lostmind.de/gtk2-perl/ppm/
ppm install Gtk2

+ Finally, restart your Windows

There are many ways but those two are the best options of all that I prefer.

Have fun!

Under Windows, it's best to use ActiveState Perl.
In order to manage your Perl package, you might want to use either:

1. Command-line approach:


C:\>perl -MCPAN -e shell;


2. Easier management through GUI:

C:\>ppm

PPM is Perl Package Manager provided by ActiveState.

Have fun!

Under Linux:


$ ./program `perl -e 'print "param"'`

Under Windows

\>perl.exe -e "exec 'program.exe','param'"

Have fun!@

There are various ways to print a perl array.
You can use a loop like this:


for( $i = 0; $i < @names; ++$i ) {
print $names[$i]." ";
}


Not a really good. How about using foreach loop?

foreach $i (@names) {
print $i." ";
}


Look better, right? But I've found a little interesting for.


for $i (@names) {
print $i." ";
}


It's still good!
How about some macro? Try this one


for (@names) {
print;
}


Uhm...but each element is not spaced out from each other..then, just make it space out


for (@names) {
print $_." ";
}


How about not using a loop? is there any way?
Oh, yeah...a great idea


print @names;


Oooops, elements are sticky together..space them out!


print "@names ";


It's better!
But I want to comma between each element, how?
In Perl, there is one special variable the set default output field seperator $,. Let's do this!


$, = ',';
print @names;


Wow! this is wonderful!
Is there any other option for printing an array?
You can join them before displaying.


print join( ',', @names);


This is a really nice trick!

Have fun!@

In order to get length of an array you can

+ either, use scalar() to force array length
+ or, take $#array_name + 1


my @letters = qw[ A B C D ];

print "Using Scalar: ".scalar( @letters )." elements.\n".
"Using Indice: ".( $#letters + 1 )." elements.\n";


Have fun!@

A little quick trick to empty an array in Perl is to set its length to a negative number.


my @fruit = qw[ apple orange berry ];
print "Before: Fruit array has ".scalar( @fruit )." elements.\n";
$#fruit = -1;
print "After: Fruit array has ".scalar( @fruit )." elements.\n";
Have fun!@

This is a small tip about sending mails via Perl code.


sub mail {
my( $to, $from, $sub, $msg ) = @_;
my( $send ) = "/usr/lib/sendmail";

open MAIL, "| $send -oi -t";
print MAIL "From: $from\n";
print MAIL "To: $to\n";
print MAIL "Subject: $sub\n\n";
print MAIL "$msg\n";
close MAIL;
}


Have fun!@

This is a quick trick to identify which operating system you are on:

#!/usr/bin/perl -v
print "The current operating system is: " . $^O;


The built-in variable $^O holds the value:
+ if you are under Windows: "MSWin32" or "Win32"
+ if you are under Linux: "linux"

Have fun!@

Eclipse is a good open-source IDE w/ wide range of programming languages, all developed and supported by community.
Especially, for a Perl IDE, I suggest you just need to stick with Eclipse and add the Perl Editor plugin. That's all! You'll have a greate Perl IDE, from editor including grammar check, syntax highlight, built-in interpretation.
Moreover, it's easier for you to organize a project.

You should check it out: EPIC - Eclipse Perl Integration
It's worth of use and great!

Have fun!@