Real Programmers/ Projects/ Barcode/ Reader.Pl
Google site:

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/};
}

All non-user content and code Copyright © 2000-2006 realprogrammers.com / Paul Makepeace. Comments & feedback welcome!