I have came across many situations where a bunch of files with one filename extension has to be renamed to another extension. Here is the way to do it in bash.
We will rename a number of post script files to PDF files ( .ps to .pdf )
safeer@penguinpower:~/Documents$ ls
book0.ps book1.ps book2.ps book3.ps book4.ps
safeer@penguinpower:~/Documents$ for file in $(ls *.ps);
do
mv $file ${file/%.ps/.pdf};
done
safeer@penguinpower:~/Documents$ ls
book0.pdf book1.pdf book2.pdf book3.pdf book4.pdf
Sunday, September 12, 2010
Saturday, August 14, 2010
Perl Snippets Part 1 - XLS to CSV
For parsing Microsoft excel files (.xls) using Perl, we can make use of the module Spreadsheet::ParseExcel.
On my Ubuntu system this module is installed by:
safeer@penguinpower:~$sudo apt-get install libspreadsheet-parseexcel-perl
Following program will take an XLS file as input and print the csv format to standard out.
On my Ubuntu system this module is installed by:
safeer@penguinpower:~$sudo apt-get install libspreadsheet-parseexcel-perl
Following program will take an XLS file as input and print the csv format to standard out.
#!/usr/bin/perl -w
use strict;
use Spreadsheet::ParseExcel;
my $parser = Spreadsheet::ParseExcel->new();
if ( !defined $ARGV[0] ) { die "Please provide an excel file"; }
my $workbook = $parser->parse($ARGV[0]);
if ( !defined $workbook ) { die $parser->error(), ".\n"; }
for my $worksheet ( $workbook->worksheets() ) {
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $row ( $row_min .. $row_max ) {
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet->get_cell( $row, $col );
if ( defined $cell ) { print $cell->value(); }
if ( $col < $col_max ) { print ","; }
}
print "\n";
}
}
Sunday, June 20, 2010
Configuring NTP service
The network time protocol ( NTP ) is used to synchronize a computer system's time with an accurate time source. Interconnected and communicating systems should have their times in sync with each other to preserve the order of communication / sotring of information ( and and many more applications ).
The ultimate source of accurate time is called a reference clock and will usually be an atomic/nuclear clocks ( usually using cesium as the element ). Another variety of reference clocks will be gps receivers receiving time from satellites ( which in turn uses an atomic clock ). Other computer systems sync their time from reference clocks directly or from servers that sync from reference clock directly.
NTP supports a hierarchy of time sources, the accuracy of each level of this hierarchy is referred to by the term startum. A startum number is given to each source based on its reliability, smallest startum being most accurate. Thus reference clocks are startum 0, the servers that sync time directly from them are startum 1, and servers that sync from these servers will be startum 2 and so on. Basiaclly if the upstream NTP server is startum X, the server syncing from that server is startum X+1 upto a maximum value of 15. NTP protocol/service has inherent mechanisms to determine the accuracy of upstream NTP server as well as its own by calculating different parameters like offset,resolution,jitter etc..
NTP is a UDP base protocol and uses port 123. Let us look at a basic NTP configuration
First install the NTP software, on ubuntu it is openntpd with main configuration file /etc/openntpd/ntpd.conf and optional include files kept under /etc/openntpd. On a redhat system it will be ntp ( with configuration file at /etc/ntp.conf and include directory /etc/ntp.d/).
safeer@ntpc:~$sudo yum install ntp
safeer@ntpc:~$sudo /sbin/service ntpd status
* ntpd is stopped
First you have to determine from which NTP server you want to sync time. This can be another server in your network, or one publicaly available. You can even setup a standalone ntp server which syncs from its own hardware clock and provide time service to other servers in your network ( though not very much recommended )
Now there are two ways to sync time from a server. You can use the ntpdate binary, which will sync with the server time immediately, but this can have adverse effect on the server of the time difference between ntpserver and client and bigger. The other option is to configure ntp service, which will allow the server to gracefully sync time.
How ntpdate works:
Check if the server is up and available:
safeer@ntpc:~$sudo ntpdate -q ntp1.safeer.in
The output will list one ore more servers behind the ntp dns name and its time details. This indicates the sever is good, so go ahead and sync with it.
safeer@ntpc:~$ sudo ntpdate ntp1.safeer.in
You can provide multiple space separated NTP server to ntpdate. If the command shows no error, the time will be set by now. Check your system with date command.
Now let us see how the ntp server can be configured:
First add one or more servers:
server 1.1.1.1
server 2.2.2.2
server ntp1.safeer.in
NTPD can detect the time drift between system clock and the reference clock ( or server ) over a period of time and need to store this somewhere to adjust the system time. This drift value has to be written to some file. The user running NTP daemon should have write access to the file.
driftfile /var/lib/ntp/drift
This much was about how you receive the time from upstream servers. Now let us see what it takes to sync the server's own system clock or downstream servers.
First case, let us assume we just need to sync the time on our server and not provide time to any downstream servers ( ntp client mode )
The configuration parameter to use here is "restrict" in the following syntax: restrict < host ip/hostname/network id > [mast < mask >] [flags .. ..]
The mask is optional ( need only when u are defining access for networks and not single servers), if the flags are omitted the server will be having unrestricted access to ntp service. Also you can use the entry "default" in place of host/network for setting default access policy. If access is not explicitly defined for a host/network the default policy will be used.
Since we are planning to sync only the local server we have to restrict everything except localhost from accessing ntp service.
## This will deny ntp service to any host that done have an explicit "restrict" entry
restrict default ignore
## Allow access to localhost through loopback interface ( by omitting flags section )
restrict 127.0.0.1
If we are configuring our server to server other hosts, say the local network - 192.168.1.0/255.255.255.0 this is how you do it:
restric 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
The flag nomodify prevent clients from modifying servers ntp configuration, notrap prevents from sending log collection trap messages, nopeer prevents peering/associating the clients with the server to be "co-servers"
If the upstream server becomes unavailable, the host will not be able to sync time, so as a fall back we configure the local clock as a time source, in ntp language the ip "127.127.1.0" indicates local clock
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
If you want to log the ntp activity add the entry
logfile /var/log/ntp.log
Finally, let us consilidate everything in one place:
server 1.1.1.1
server 2.2.2.2
server ntp1.safeer.in
restrict default ignore
restrict 127.0.0.1
restric 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
driftfile /var/lib/ntp/drift
logfile /var/log/ntp.log
Before starting ntp service, run ntpdate with one of the servers listed as an initial sync, then start ntp service
safeer@ntpc:~$sudo ntpdate ntp1.safeer.in
safeer@ntpc:~$sudo /sbin/service ntpd start
For more on NTP, check official website and RFC page.
The ultimate source of accurate time is called a reference clock and will usually be an atomic/nuclear clocks ( usually using cesium as the element ). Another variety of reference clocks will be gps receivers receiving time from satellites ( which in turn uses an atomic clock ). Other computer systems sync their time from reference clocks directly or from servers that sync from reference clock directly.
NTP supports a hierarchy of time sources, the accuracy of each level of this hierarchy is referred to by the term startum. A startum number is given to each source based on its reliability, smallest startum being most accurate. Thus reference clocks are startum 0, the servers that sync time directly from them are startum 1, and servers that sync from these servers will be startum 2 and so on. Basiaclly if the upstream NTP server is startum X, the server syncing from that server is startum X+1 upto a maximum value of 15. NTP protocol/service has inherent mechanisms to determine the accuracy of upstream NTP server as well as its own by calculating different parameters like offset,resolution,jitter etc..
NTP is a UDP base protocol and uses port 123. Let us look at a basic NTP configuration
First install the NTP software, on ubuntu it is openntpd with main configuration file /etc/openntpd/ntpd.conf and optional include files kept under /etc/openntpd. On a redhat system it will be ntp ( with configuration file at /etc/ntp.conf and include directory /etc/ntp.d/).
safeer@ntpc:~$sudo yum install ntp
safeer@ntpc:~$sudo /sbin/service ntpd status
* ntpd is stopped
First you have to determine from which NTP server you want to sync time. This can be another server in your network, or one publicaly available. You can even setup a standalone ntp server which syncs from its own hardware clock and provide time service to other servers in your network ( though not very much recommended )
Now there are two ways to sync time from a server. You can use the ntpdate binary, which will sync with the server time immediately, but this can have adverse effect on the server of the time difference between ntpserver and client and bigger. The other option is to configure ntp service, which will allow the server to gracefully sync time.
How ntpdate works:
Check if the server is up and available:
safeer@ntpc:~$sudo ntpdate -q ntp1.safeer.in
The output will list one ore more servers behind the ntp dns name and its time details. This indicates the sever is good, so go ahead and sync with it.
safeer@ntpc:~$ sudo ntpdate ntp1.safeer.in
You can provide multiple space separated NTP server to ntpdate. If the command shows no error, the time will be set by now. Check your system with date command.
Now let us see how the ntp server can be configured:
First add one or more servers:
server 1.1.1.1
server 2.2.2.2
server ntp1.safeer.in
NTPD can detect the time drift between system clock and the reference clock ( or server ) over a period of time and need to store this somewhere to adjust the system time. This drift value has to be written to some file. The user running NTP daemon should have write access to the file.
driftfile /var/lib/ntp/drift
This much was about how you receive the time from upstream servers. Now let us see what it takes to sync the server's own system clock or downstream servers.
First case, let us assume we just need to sync the time on our server and not provide time to any downstream servers ( ntp client mode )
The configuration parameter to use here is "restrict" in the following syntax: restrict < host ip/hostname/network id > [mast < mask >] [flags .. ..]
The mask is optional ( need only when u are defining access for networks and not single servers), if the flags are omitted the server will be having unrestricted access to ntp service. Also you can use the entry "default" in place of host/network for setting default access policy. If access is not explicitly defined for a host/network the default policy will be used.
Since we are planning to sync only the local server we have to restrict everything except localhost from accessing ntp service.
## This will deny ntp service to any host that done have an explicit "restrict" entry
restrict default ignore
## Allow access to localhost through loopback interface ( by omitting flags section )
restrict 127.0.0.1
If we are configuring our server to server other hosts, say the local network - 192.168.1.0/255.255.255.0 this is how you do it:
restric 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
The flag nomodify prevent clients from modifying servers ntp configuration, notrap prevents from sending log collection trap messages, nopeer prevents peering/associating the clients with the server to be "co-servers"
If the upstream server becomes unavailable, the host will not be able to sync time, so as a fall back we configure the local clock as a time source, in ntp language the ip "127.127.1.0" indicates local clock
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
If you want to log the ntp activity add the entry
logfile /var/log/ntp.log
Finally, let us consilidate everything in one place:
server 1.1.1.1
server 2.2.2.2
server ntp1.safeer.in
restrict default ignore
restrict 127.0.0.1
restric 192.168.1.0 mask 255.255.255.0 nomodify notrap nopeer
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
driftfile /var/lib/ntp/drift
logfile /var/log/ntp.log
Before starting ntp service, run ntpdate with one of the servers listed as an initial sync, then start ntp service
safeer@ntpc:~$sudo ntpdate ntp1.safeer.in
safeer@ntpc:~$sudo /sbin/service ntpd start
For more on NTP, check official website and RFC page.
Tuesday, April 6, 2010
Converting time between timezones in Linux
People working with systems that are located in different timezones are always faced with the problem of converting time between timezones. On GNU Linux systems ( and most other POSIX OSs) you can manipulate the TZ environment variable to achieve this.
Generally on Linux systems, the timezone information is kept in the file /etc/localtime. This file is usually a softlink to an appropriate zone file under the location "/usr/share/zoneinfo/".
safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Africa
drwxr-xr-x 6 root root 12288 2010-02-21 01:46 America
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Antarctica
.............................
-rw-r--r-- 1 root root 2294 2010-01-03 01:38 EST5EDT
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Etc
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Europe
.............................
-rw-r--r-- 1 root root 118 2010-01-03 01:38 UTC
-rw-r--r-- 1 root root 1873 2010-01-03 01:38 WET
-rw-r--r-- 1 root root 2194 2010-01-03 01:38 W-SU
-rw-r--r-- 1 root root 18896 2009-12-12 20:27 zone.tab
-rw-r--r-- 1 root root 118 2010-01-03 01:38 Zulu
Some of these are directories which have timezone files under them. For eg, the directory Asia contains zone files for all the countries ( or their capital/important cities) in Asia, including India,China,Pakistan etc....
safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/Asia/
-rw-r--r-- 1 root root 157 2010-01-03 01:38 Aden
-rw-r--r-- 1 root root 922 2010-01-03 01:38 Almaty
-rw-r--r-- 1 root root 8504 2010-01-03 01:38 Amman
............................
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashgabat
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashkhabad
-rw-r--r-- 1 root root 962 2010-01-03 01:38 Baghdad
...............
-rw-r--r-- 1 root root 1929 2010-01-03 01:38 Vladivostok
-rw-r--r-- 1 root root 1914 2010-01-03 01:38 Yakutsk
-rw-r--r-- 1 root root 2000 2010-01-03 01:38 Yekaterinburg
-rw-r--r-- 1 root root 2012 2010-01-03 01:38 Yerevan
We are going to use this directory structure for setting the TZ variable. The value of TZ variable will be the relative path of the desired timezone file with reference to "/usr/share/zoneinfo". As an example, I am going to change my system time to Singapore time.
safeer@penguinpower:~$ date
Tue Apr 6 00:44:54 IST 2010
safeer@penguinpower:~$ export TZ=Asia/Singapore
safeer@penguinpower:~$ date
Tue Apr 6 03:15:37 SGT 2010
What if you don't want to set the TZ variable but just need to see the current Singapore time?
safeer@penguinpower:~$ date
Tue Apr 6 00:48:07 IST 2010
safeer@penguinpower:~$ TZ=Asia/Singapore date
Tue Apr 6 03:18:12 SGT 2010
safeer@penguinpower:~$ date
Tue Apr 6 00:48:16 IST 2010
Here the value "Asia/Singapore" will be applicable only to the command 'date' during its execution.
We are going to use this, along with a feature of 'date' command for converting between different timezones.
Now our machine's timezone is India Standard Time (IST - Asia/Calcutta ), we need to see what will be the time in India when the Singapore time is 2:24 PM on a particular day.
safeer@penguinpower:~$ date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 11:54:00 IST 2010
This shows that SGT is two and half hours ahead of IST. The -d option allows specifying a TZ variable which helped us in getting this answer. Now suppose that you want to see what will be the time in Dubai when it is 2.30 PM in Singapore. But our local timezone is in IST and should not be changed.
The way to do this is, set the TZ variable to Dubai timezone just for the particular date command. Here is how we can do it.
safeer@penguinpower:~$ TZ=Asia/Dubai date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 10:24:00 GST 2010
This shows us that, Dubai time ( GST - Gulf Standard Time) is 4 hours behind Singapore time (SGT).
So the general syntax for conversion can be summarized as below:
TZ=$TO_TIMEZONE date -d 'TZ="$FROM_TIMEZONE" YYYY-MM-DD HH:MM:SS'
Where $FROM_TIMEZONE is the timezone from which the conversion should be done and $TO_TIMEZONE is the timezone to which the date should be converted. Here:
TO_TIMEZONE=Asia/Calcutta, FROM_TIMEZONE=Asia/Singapore
If you regularly do date conversions you can write a wrapper script around this command.
To learn more about TZ variable, please visit TZ page on GNU website
Generally on Linux systems, the timezone information is kept in the file /etc/localtime. This file is usually a softlink to an appropriate zone file under the location "/usr/share/zoneinfo/".
safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Africa
drwxr-xr-x 6 root root 12288 2010-02-21 01:46 America
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Antarctica
.............................
-rw-r--r-- 1 root root 2294 2010-01-03 01:38 EST5EDT
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Etc
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Europe
.............................
-rw-r--r-- 1 root root 118 2010-01-03 01:38 UTC
-rw-r--r-- 1 root root 1873 2010-01-03 01:38 WET
-rw-r--r-- 1 root root 2194 2010-01-03 01:38 W-SU
-rw-r--r-- 1 root root 18896 2009-12-12 20:27 zone.tab
-rw-r--r-- 1 root root 118 2010-01-03 01:38 Zulu
Some of these are directories which have timezone files under them. For eg, the directory Asia contains zone files for all the countries ( or their capital/important cities) in Asia, including India,China,Pakistan etc....
safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/Asia/
-rw-r--r-- 1 root root 157 2010-01-03 01:38 Aden
-rw-r--r-- 1 root root 922 2010-01-03 01:38 Almaty
-rw-r--r-- 1 root root 8504 2010-01-03 01:38 Amman
............................
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashgabat
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashkhabad
-rw-r--r-- 1 root root 962 2010-01-03 01:38 Baghdad
...............
-rw-r--r-- 1 root root 1929 2010-01-03 01:38 Vladivostok
-rw-r--r-- 1 root root 1914 2010-01-03 01:38 Yakutsk
-rw-r--r-- 1 root root 2000 2010-01-03 01:38 Yekaterinburg
-rw-r--r-- 1 root root 2012 2010-01-03 01:38 Yerevan
We are going to use this directory structure for setting the TZ variable. The value of TZ variable will be the relative path of the desired timezone file with reference to "/usr/share/zoneinfo". As an example, I am going to change my system time to Singapore time.
safeer@penguinpower:~$ date
Tue Apr 6 00:44:54 IST 2010
safeer@penguinpower:~$ export TZ=Asia/Singapore
safeer@penguinpower:~$ date
Tue Apr 6 03:15:37 SGT 2010
What if you don't want to set the TZ variable but just need to see the current Singapore time?
safeer@penguinpower:~$ date
Tue Apr 6 00:48:07 IST 2010
safeer@penguinpower:~$ TZ=Asia/Singapore date
Tue Apr 6 03:18:12 SGT 2010
safeer@penguinpower:~$ date
Tue Apr 6 00:48:16 IST 2010
Here the value "Asia/Singapore" will be applicable only to the command 'date' during its execution.
We are going to use this, along with a feature of 'date' command for converting between different timezones.
Now our machine's timezone is India Standard Time (IST - Asia/Calcutta ), we need to see what will be the time in India when the Singapore time is 2:24 PM on a particular day.
safeer@penguinpower:~$ date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 11:54:00 IST 2010
This shows that SGT is two and half hours ahead of IST. The -d option allows specifying a TZ variable which helped us in getting this answer. Now suppose that you want to see what will be the time in Dubai when it is 2.30 PM in Singapore. But our local timezone is in IST and should not be changed.
The way to do this is, set the TZ variable to Dubai timezone just for the particular date command. Here is how we can do it.
safeer@penguinpower:~$ TZ=Asia/Dubai date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 10:24:00 GST 2010
This shows us that, Dubai time ( GST - Gulf Standard Time) is 4 hours behind Singapore time (SGT).
So the general syntax for conversion can be summarized as below:
TZ=$TO_TIMEZONE date -d 'TZ="$FROM_TIMEZONE" YYYY-MM-DD HH:MM:SS'
Where $FROM_TIMEZONE is the timezone from which the conversion should be done and $TO_TIMEZONE is the timezone to which the date should be converted. Here:
TO_TIMEZONE=Asia/Calcutta, FROM_TIMEZONE=Asia/Singapore
If you regularly do date conversions you can write a wrapper script around this command.
To learn more about TZ variable, please visit TZ page on GNU website
Wednesday, February 17, 2010
Base64 Encoding and Decoding
base64 is an encoding scheme used to transfer binary/text data across networks. Though initially used predominantly for transmitting data through email, base64 is used in a wide variety of of applications nowadays.
The encoding is done by converting input data into printable ASCII characters. The input stream is divided into 6 bit segments and converted to a printable character from a set of 64 encoding characters based on the value of the 6 bits ( 6 bits can represent a value between 0 to 63 - 64 numbers ). In practical dividing by 6 bits is done by taking 3 consecutive bytes (3 x 8 bits = 4 x 6 bits ) of the input stream and converting it to 4 encoding characters. If the total number of bytes in the input stream is not a multiple of three, extra 0 value bytes are padded to the end of the stream to make it multiple of three.
The decoding of the input stream is done on the receiving end by reversing the above method.
In Linux, the "base64" command is used to decode/encode base64. Let us see an example. We will convert the "ls" command binary to base64 and back and see if the resultant binary is still working as "ls".
safeer@penguinpower:~/TMP$ cp /bin/ls .
safeer@penguinpower:~/TMP$ /home/safeer/TMP/ls
ls
Convert the binary to base64
safeer@penguinpower:~/TMP$ cat /home/safeer/TMP/ls | base64 > ls.encoded
Compare both
safeer@penguinpower:~/TMP$ wc ls ls.encoded
503 3271 104508 ls
1834 1834 141178 ls.encoded
2337 5105 245686 total
safeer@penguinpower:~/TMP$ head -1 ls.encoded
f0VMRgEBAQAAAAAAAAAAAAIAAwABAAAANL4ECDQAAADckwEAAAAAADQAIAAJACgAHAAbAAYAAAA0
safeer@penguinpower:~/TMP$ tail -1 ls.encoded
AAAA6JIBAPIAAAAAAAAAAAAAAAEAAAAAAAAA
safeer@penguinpower:~/TMP$ file ls.encoded
ls.encoded: ASCII text
safeer@penguinpower:~/TMP$ file ls
ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x83531f308f1fa18221be53eaf399303400c14638, stripped
Now convert the encoded data back
safeer@penguinpower:~/TMP$ cat ls.encoded |base64 -d > ls.decoded
Compare with original "ls" binary
safeer@penguinpower:~/TMP$ wc ls ls.decoded
503 3271 104508 ls
503 3271 104508 ls.decoded
1006 6542 209016 total
safeer@penguinpower:~/TMP$ file ls.decoded
ls.decoded: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x83531f308f1fa18221be53eaf399303400c14638, stripped
safeer@penguinpower:~/TMP$ chmod a+x ls.decoded
safeer@penguinpower:~/TMP$ /home/safeer/TMP/ls.decoded
ls ls.decoded ls.encoded
Now that you know how the conversion works, let us see some other ways to decode/encode using base64. We will use a simple string this time for simplicity.
Bash
Encoding
safeer@penguinpower:~/TMP$ printf "safeer"|base64
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ printf "c2FmZWVy"|base64 -d
safeer
Perl
Encoding
safeer@penguinpower:~/TMP$ perl -MMIME::Base64 -e 'print encode_base64("safeer");'
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ perl -MMIME::Base64 -e 'print decode_base64("c2FmZWVy");'
safeer
PHP
Encoding
safeer@penguinpower:~/TMP$ php -r "print base64_encode('safeer');"
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ php -r "echo base64_decode('c2FmZWVy');"
safeer
Python
Encoding
safeer@penguinpower:~/TMP$ python -c "import base64;print base64.b64encode('safeer')"
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ python -c "import base64;print base64.b64decode('c2FmZWVy')"
safeer
The encoding is done by converting input data into printable ASCII characters. The input stream is divided into 6 bit segments and converted to a printable character from a set of 64 encoding characters based on the value of the 6 bits ( 6 bits can represent a value between 0 to 63 - 64 numbers ). In practical dividing by 6 bits is done by taking 3 consecutive bytes (3 x 8 bits = 4 x 6 bits ) of the input stream and converting it to 4 encoding characters. If the total number of bytes in the input stream is not a multiple of three, extra 0 value bytes are padded to the end of the stream to make it multiple of three.
The decoding of the input stream is done on the receiving end by reversing the above method.
In Linux, the "base64" command is used to decode/encode base64. Let us see an example. We will convert the "ls" command binary to base64 and back and see if the resultant binary is still working as "ls".
safeer@penguinpower:~/TMP$ cp /bin/ls .
safeer@penguinpower:~/TMP$ /home/safeer/TMP/ls
ls
Convert the binary to base64
safeer@penguinpower:~/TMP$ cat /home/safeer/TMP/ls | base64 > ls.encoded
Compare both
safeer@penguinpower:~/TMP$ wc ls ls.encoded
503 3271 104508 ls
1834 1834 141178 ls.encoded
2337 5105 245686 total
safeer@penguinpower:~/TMP$ head -1 ls.encoded
f0VMRgEBAQAAAAAAAAAAAAIAAwABAAAANL4ECDQAAADckwEAAAAAADQAIAAJACgAHAAbAAYAAAA0
safeer@penguinpower:~/TMP$ tail -1 ls.encoded
AAAA6JIBAPIAAAAAAAAAAAAAAAEAAAAAAAAA
safeer@penguinpower:~/TMP$ file ls.encoded
ls.encoded: ASCII text
safeer@penguinpower:~/TMP$ file ls
ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x83531f308f1fa18221be53eaf399303400c14638, stripped
Now convert the encoded data back
safeer@penguinpower:~/TMP$ cat ls.encoded |base64 -d > ls.decoded
Compare with original "ls" binary
safeer@penguinpower:~/TMP$ wc ls ls.decoded
503 3271 104508 ls
503 3271 104508 ls.decoded
1006 6542 209016 total
safeer@penguinpower:~/TMP$ file ls.decoded
ls.decoded: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x83531f308f1fa18221be53eaf399303400c14638, stripped
safeer@penguinpower:~/TMP$ chmod a+x ls.decoded
safeer@penguinpower:~/TMP$ /home/safeer/TMP/ls.decoded
ls ls.decoded ls.encoded
Now that you know how the conversion works, let us see some other ways to decode/encode using base64. We will use a simple string this time for simplicity.
Bash
Encoding
safeer@penguinpower:~/TMP$ printf "safeer"|base64
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ printf "c2FmZWVy"|base64 -d
safeer
Perl
Encoding
safeer@penguinpower:~/TMP$ perl -MMIME::Base64 -e 'print encode_base64("safeer");'
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ perl -MMIME::Base64 -e 'print decode_base64("c2FmZWVy");'
safeer
PHP
Encoding
safeer@penguinpower:~/TMP$ php -r "print base64_encode('safeer');"
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ php -r "echo base64_decode('c2FmZWVy');"
safeer
Python
Encoding
safeer@penguinpower:~/TMP$ python -c "import base64;print base64.b64encode('safeer')"
c2FmZWVy
Decoding
safeer@penguinpower:~/TMP$ python -c "import base64;print base64.b64decode('c2FmZWVy')"
safeer
Subscribe to:
Posts (Atom)