Tuesday, February 28, 2006

Convert EANs to ISBNs in Ruby

A few weeks ago I acquired a modified CueCat on eBay so that I could have a basic barcode scanner. One of the things I had in mind was to scan the ISBN bar codes on my books so I can get an inventory of what I have. After reading "The Book-Scanning Project" I knew going into it that I'd have to convert EANs to ISBNs, but that seemed like a good way to flex my nascent Ruby chops. So based on the JavaScript and Java versions provided at the aforementioned site, here's my version in Ruby:

#!/usr/bin/ruby
ARGF.each {|line|
if line =~ /^978/
isbn = line.slice(3,9)
xsum = 0
(0..9).each { |i|
xsum += (10 - i) * isbn.slice(i,1).to_i
}
xsum %= 11
xsum = 11 - xsum
xsum = case xsum
when 10 then "X"
when 11 then 0
else xsum
end
isbn = isbn + xsum.to_s
puts isbn
end
}

Paste this into a .rb file, chmod u+x it, and then you can run it on a file of EANs like this:

9780385493628 51200
9780486253466
9780345379184 51400
9780345409461 51400
9780684813783
9780618056767 90000

Giving as output:

0385493622
0486253465
0345379187
0345409469
0684813785
0618056769

Note that it's not necessary to have scanned the last 5 digits of the EAN bar code -- only the first 13 (starting with 978...) matter. Also, I've tried to do this in a "native" Ruby way, not as if it were Perl transposed into another interpreter -- but if it looks too Perlish, I'm happy to have someone more familiar with Ruby offer suggestions.

1 comment:

Anonymous said...

#! /usr/bin/env ruby
# Convert an EAN barcode into an ISBN:
# * strip the leading 978
# * ignore the terminal checksum
# * append new checksum
ARGF.each { |line|
if line =~ /^978/
isbn = line[3..11]
xsum = 0
(0..8).each { |i|
xsum += (i + 1) * isbn[i].chr.to_i
}
xsum %= 11
xsum == 10 && xsum = "X"
puts isbn + xsum.to_s
end
}



I dunno if it's much more Rubyish, but it's shorter, and has comments... think it even does the same thing

www.flickr.com