realprogrammers.com
#!/usr/bin/perl -w
use strict;
my $serial = '/dev/ttyS0';
system "/bin/stty -F $serial 9600 cs7 -parodd -cstopb icanon icrnl";
open SERIAL, "<$serial" or die "Can't open port $serial: $!\n";
while (defined (my $barcode = <SERIAL>)) {
chomp $barcode;
# is this an EAN and if so, a book?
if (length($barcode) == 13 && substr($barcode, 0, 3) == '978') {
my $isbn = ean_to_isbn($barcode);
my $amazon_url = amazon_search_url($isbn);
print_to_xclip($amazon_url);
print "$barcode -> $isbn; $amazon_url\n";
} else {
print "$barcode\n";
}
}
# print_to_xclip:
# print a string to the xclip program. xclip only accept input
# on stdin.
sub print_to_xclip {
my $string = shift;
if (open XCLIP, "| xclip -i") {
print XCLIP $string;
close XCLIP;
} else {
warn "Couldn't pipe to xclip: $!\n";
}
}
# ean_to_isbn:
# The barcode is typically a 13-digit EAN (European Article Number).
# All books' first 3 digits are 978, and the final digit is a
# checksum. The ISBN is in the 9 digits positions 4 through 12 of the
# EAN. The complete ISBN is those 9 digits plus a checksum, calculated
# from the ISBN.
sub ean_to_isbn {
my $ean = shift;
my $isbnbase = substr $ean, 3, -1; # skip first three and last one
my $check_sum = my $pos = 0;
$check_sum += $_ * (10 - $pos++) foreach split //, $isbnbase;
$check_sum = (11 - $check_sum % 11) % 11;
$isbnbase . ($check_sum == 10 ? 'X' : $check_sum);
}
sub amazon_search_url {
my $isbn = shift;
qq{http://www.amazon.com/exec/obidos/ASIN/$isbn/};
}