|
|
 |
 |
 |
 |
Ruby Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Checking Credit Cards (#122)
The three rules of Ruby Quiz: 1. Please do not post any solutions or spoiler discussion for this quiz until 48 hours have passed from the time on this message. 2. Support Ruby Quiz by submitting ideas as often as you can: http://www.rubyquiz.com/ 3. Enjoy! Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone on Ruby Talk follow the discussion. Please reply to the original quiz message, if you can. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-= Before a credit card is submitted to a financial institution, it generally makes sense to run some simple reality checks on the number. The numbers are a good length and it's common to make minor transcription errors when the card is not scanned directly. The first check people often do is to validate that the card matches a known pattern from one of the accepted card providers. Some of these patterns are: +============+=============+===============+ | Card Type | Begins With | Number Length | +============+=============+===============+ | AMEX | 34 or 37 | 15 | +------------+-------------+---------------+ | Discover | 6011 | 16 | +------------+-------------+---------------+ | MasterCard | 51-55 | 16 | +------------+-------------+---------------+ | Visa | 4 | 13 or 16 | +------------+-------------+---------------+ All of these card types also generate numbers such that they can be validated by the Luhn algorithm, so that's the second check systems usually try. The steps are: 1. Starting with the next to last digit and continuing with every other digit going back to the beginning of the card, double the digit 2. Sum all doubled and untouched digits in the number 3. If that total is a multiple of 10, the number is valid For example, given the card number 4408 0412 3456 7893: Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 Step 3: 70 % 10 == 0 Thus that card is valid. Let's try one more, 4417 1234 5678 9112: Step 1: 8 4 2 7 2 2 6 4 10 6 14 8 18 1 2 2 Step 2: 8+4+2+7+2+2+6+4+1+0+6+1+4+8+1+8+1+2+2 = 69 Step 3: 69 % 10 != 0 That card is not valid. This week's Ruby Quiz is to write a program that accepts a credit card number as a command-line argument. The program should print the card's type (or Unknown) as well a Valid/Invalid indication of whether or not the card passes the Luhn algorithm.
On Apr 27, 2007, at 8:59 PM, Ruby Quiz wrote:
> The three rules of Ruby Quiz: > 1. Please do not post any solutions or spoiler discussion for this > quiz until > 48 hours have passed from the time on this message. > 2. Support Ruby Quiz by submitting ideas as often as you can: > http://www.rubyquiz.com/ > 3. Enjoy! > Suggestion: A [QUIZ] in the subject of emails about the problem > helps everyone > on Ruby Talk follow the discussion. Please reply to the original > quiz message, > if you can. > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > =-=-=-=-=-=-= > Before a credit card is submitted to a financial institution, it > generally makes > sense to run some simple reality checks on the number. The numbers > are a good > length and it's common to make minor transcription errors when the > card is not > scanned directly. > The first check people often do is to validate that the card > matches a known > pattern from one of the accepted card providers. Some of these > patterns are: > +============+=============+===============+ > | Card Type | Begins With | Number Length | > +============+=============+===============+ > | AMEX | 34 or 37 | 15 | > +------------+-------------+---------------+ > | Discover | 6011 | 16 | > +------------+-------------+---------------+ > | MasterCard | 51-55 | 16 | > +------------+-------------+---------------+ > | Visa | 4 | 13 or 16 | > +------------+-------------+---------------+ > All of these card types also generate numbers such that they can be > validated by > the Luhn algorithm, so that's the second check systems usually > try. The steps > are: > 1. Starting with the next to last digit and continuing with every > other > digit going back to the beginning of the card, double the digit > 2. Sum all doubled and untouched digits in the number > 3. If that total is a multiple of 10, the number is valid > For example, given the card number 4408 0412 3456 7893: > Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 > Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 > Step 3: 70 % 10 == 0 > Thus that card is valid. > Let's try one more, 4417 1234 5678 9112: > Step 1: 8 4 2 7 2 2 6 4 10 6 14 8 18 1 2 2 > Step 2: 8+4+2+7+2+2+6+4+1+0+6+1+4+8+1+8+1+2+2 = 69 > Step 3: 69 % 10 != 0 > That card is not valid. > This week's Ruby Quiz is to write a program that accepts a credit > card number as > a command-line argument. The program should print the card's type > (or Unknown) > as well a Valid/Invalid indication of whether or not the card > passes the Luhn > algorithm.
For completeness and to make this Quiz exercise valid to more people, can anyone include the information for other major credit cards from major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , etc... This would be good to expand the exercise and return more to our friends in various areas! Discover is itself not found outside of North America, AFIK.
> For completeness and to make this Quiz exercise valid to more people, > can anyone include the information for other major credit cards from > major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , etc...
UK had Switch and Solo till recently which are now rebranded under the Maestro umbrella. They're not really credit cards and basically no rules exist, you have to check tables to determine valid prefixes and card number length. Additionally, Maestro card numbers may also be Mastercard numbers, so they can't be uniquely identified as being Maestro. For JCB and Diner's: JCB 3528-2589 Length: 16 Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 Cheers, -Tim
Ruby Quiz <j @grayproductions.net> writes: > This week's Ruby Quiz is to write a program that accepts a credit > card number as a command-line argument. The program should print > the card's type (or Unknown) as well a Valid/Invalid indication of > whether or not the card passes the Luhn algorithm. May I make an additional suggestion? Treat spaces in the card number as perfectly valid, and simply strip them before processing. One of the most irritating features found in many online stores is the requirement that the credit card number be typed in with no spaces. (The other biggie is using a select box for the state abbreviation) Now granted, for accepting the card number from the command line this will mean that on the command line the card number was quoted, but presumably most people's programs will be a command-line wrapper around a function/class that does the real work. -- s=%q( Daniel Martin -- mar@snowplow.org puts "s=%q(#{s})",s.to_a[1] ) puts "s=%q(#{s})",s.to_a[1]
On Apr 27, 2007, at 7:36 AM, Daniel Martin wrote: > Now granted, for accepting the card number from the command line this > will mean that on the command line the card number was quoted...
It doesn't have to mean that: $ ruby -e 'p ARGV.join' 1111 2222 3333 4444 "1111222233334444" James Edward Gray II
On Apr 27, 2007, at 9:22 PM, Tim Becker wrote:
>> For completeness and to make this Quiz exercise valid to more people, >> can anyone include the information for other major credit cards from >> major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , >> etc... > UK had Switch and Solo till recently which are now rebranded under the > Maestro umbrella. They're not really credit cards and basically no > rules exist, you have to check tables to determine valid prefixes and > card number length. Additionally, Maestro card numbers may also be > Mastercard numbers, so they can't be uniquely identified as being > Maestro. > For JCB and Diner's: > JCB 3528-2589 Length: 16 > Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 > Cheers, > -Tim
Wow, those are some broad ranges.
> > JCB 3528-2589 Length: 16
should be 3528-3589, obviously. > > Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 > Wow, those are some broad ranges.
Well, those ranges DO include Carte Blanche :) I haven't seen a physical Diners Card in at least 20 years to be honest, not sure who still uses them. If you think those ranges are broad, the last UK-Switch/Solo table I had has over 180 card prefixes with different card lengths...
On Apr 27, 2007, at 10:37 PM, Tim Becker wrote: >> > JCB 3528-2589 Length: 16 > should be 3528-3589, obviously. >> > Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 >> Wow, those are some broad ranges. > Well, those ranges DO include Carte Blanche :) I haven't seen a > physical Diners Card in at least 20 years to be honest, not sure who > still uses them. > If you think those ranges are broad, the last UK-Switch/Solo table I > had has over 180 card prefixes with different card lengths...
My grandmother used to have a Diners Club card. Last time I saw that was about 20 years ago too. But of the cards accepted here in Tokyo, Diners Club is one that is often listed! (in bars and restaurants of course) Oh, I can only imagine. Processing cards with less deeply thought out numbering schemes. The big boys planned that stuff back when computing power was a premium.
> +============+=============+===============+ > | Card Type | Begins With | Number Length | > +============+=============+===============+ > | AMEX | 34 or 37 | 15 | > +------------+-------------+---------------+ > | Discover | 6011 | 16 | > +------------+-------------+---------------+ > | MasterCard | 51-55 | 16 | > +------------+-------------+---------------+ > | Visa | 4 | 13 or 16 | > +------------+-------------+---------------+
So is a card number like "4012 3456 7890" a valid Unknown, or an invalid Visa? Similarly, for Unknown, should we accept any length, or go for the common 16?
On Apr 27, 2007, at 12:58 PM, Matthew Moss wrote: >> +============+=============+===============+ >> | Card Type | Begins With | Number Length | >> +============+=============+===============+ >> | AMEX | 34 or 37 | 15 | >> +------------+-------------+---------------+ >> | Discover | 6011 | 16 | >> +------------+-------------+---------------+ >> | MasterCard | 51-55 | 16 | >> +------------+-------------+---------------+ >> | Visa | 4 | 13 or 16 | >> +------------+-------------+---------------+ > So is a card number like "4012 3456 7890" a valid Unknown, or an > invalid Visa?
Visa Invalid Always match the type first. > Similarly, for Unknown, should we accept any length, or go for the > common 16?
Unknown is for any type that doesn't match, so it could be any length. James Edward Gray II
So I took this as an opportunity to try doing a little TDD, something which is appealing but I've never really tried. It _is_ fun to see failure first and then fix. =) There are probably other tests I could have included, but here is a start, in case people want to check a few numbers or add more tests: Obviously, you may need to change this to match your solution... require "test/unit" require "ccard" class CreditCardCheckTest < Test::Unit::TestCase def test_valid_numbers assert CreditCard.new("4408041234567893").valid? assert CreditCard.new("6011111111111117").valid? end def test_invalid_nubers assert !CreditCard.new("4417123456789112").valid? end def test_valid_numbers_with_spaces assert CreditCard.new("4408 0412 3456 7893").valid? assert CreditCard.new("6011 1111 1111 1117").valid? end def test_invalid_nubers_with_spaces assert !CreditCard.new("4417 1234 5678 9112").valid? end def test_valid_types assert_equal CreditCard.new("4408041234567893").type, :visa assert_equal CreditCard.new("4408 0412 3456 7893").type, :visa assert_equal CreditCard.new("6011 1111 1111 1117").type, :discover assert_equal CreditCard.new("123456789").type, :unknown end def test_invalid_types assert_nil CreditCard.new("4408 0412 3456 789").type end end
James Edward Gray II wrote: > On Apr 27, 2007, at 12:58 PM, Matthew Moss wrote: >> So is a card number like "4012 3456 7890" a valid Unknown, or an >> invalid Visa? > Visa Invalid > Always match the type first.
Nope thats no Visa number but a unknown one. Visa Cards have a certain length (13 or 16) and if that length doesn't fit (Matthew's number here had just 12 digits)it's unknown :) otherwise the length would be obsolete don't you think? Both length and startingbytes have equal weight in the decision wether a card belongs to a known Company or not. -- greets ( ) ( /\ .-"""-. /\ //\\/ ,,, \//\\ |/\| ,;;;;;, |/\| //\\\;-"""-;///\\ // \/ . \/ \\ (| ,-_| \ | / |_-, |) //`__\.-.-./__`\\ // /.-(() ())-.\ \\ (\ |) '---' (| /) ` (| |) ` jgs \) (/ one must still have chaos in oneself to be able to give birth to a dancing star
On Apr 27, 2007, at 3:10 PM, anansi wrote: > James Edward Gray II wrote: >> On Apr 27, 2007, at 12:58 PM, Matthew Moss wrote: >>> So is a card number like "4012 3456 7890" a valid Unknown, or an >>> invalid Visa? >> Visa Invalid >> Always match the type first. > Nope thats no Visa number but a unknown one. Visa Cards have a > certain length (13 or 16) and if that length doesn't fit (Matthew's > number here had just 12 digits)it's unknown :) otherwise the length > would be obsolete don't you think? > Both length and startingbytes have equal weight in the decision > wether a card belongs to a known Company or not.
You are right. I didn't read well. It's Unknown. James Edward Gray II
Tim Becker wrote: >> For completeness and to make this Quiz exercise valid to more people, >> can anyone include the information for other major credit cards from >> major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , etc... > UK had Switch and Solo till recently which are now rebranded under the > Maestro umbrella. They're not really credit cards and basically no > rules exist, you have to check tables to determine valid prefixes and > card number length. Additionally, Maestro card numbers may also be > Mastercard numbers, so they can't be uniquely identified as being > Maestro. > For JCB and Diner's: > JCB 3528-2589 Length: 16 > Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14
There's no way to differentiate between a JCB starting with 34 and an American Express card that starts with 34 given those starting numbers. Raj
On Apr 27, 2007, at 8:39 PM, Raj Sahae wrote:
> Tim Becker wrote: >>> For completeness and to make this Quiz exercise valid to more >>> people, >>> can anyone include the information for other major credit cards from >>> major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , >>> etc... >> UK had Switch and Solo till recently which are now rebranded under >> the >> Maestro umbrella. They're not really credit cards and basically no >> rules exist, you have to check tables to determine valid prefixes and >> card number length. Additionally, Maestro card numbers may also be >> Mastercard numbers, so they can't be uniquely identified as being >> Maestro. >> For JCB and Diner's: >> JCB 3528-2589 Length: 16 >> Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 > There's no way to differentiate between a JCB starting with 34 and > an American Express card that starts with 34 given those starting > numbers.
Tim corrected his typo: >> > JCB 3528-2589 Length: 16 > should be 3528-3589, obviously.
So I don't think a leading 34 is ambiguous. It would be American Express, with an expected length of 15 digits. -Mark
Mark Day wrote: > On Apr 27, 2007, at 8:39 PM, Raj Sahae wrote: >> Tim Becker wrote: >>>> For completeness and to make this Quiz exercise valid to more people, >>>> can anyone include the information for other major credit cards from >>>> major countries? Japan: JCB, et. al., U.K.: Barclay, et. al. , etc... >>> UK had Switch and Solo till recently which are now rebranded under the >>> Maestro umbrella. They're not really credit cards and basically no >>> rules exist, you have to check tables to determine valid prefixes and >>> card number length. Additionally, Maestro card numbers may also be >>> Mastercard numbers, so they can't be uniquely identified as being >>> Maestro. >>> For JCB and Diner's: >>> JCB 3528-2589 Length: 16 >>> Diners 3000-3029, 3040-3059, 36, 3815-3889, 389 Length: 14 >> There's no way to differentiate between a JCB starting with 34 and an >> American Express card that starts with 34 given those starting numbers. > Tim corrected his typo: >>> > JCB 3528-2589 Length: 16 >> should be 3528-3589, obviously. > So I don't think a leading 34 is ambiguous. It would be American > Express, with an expected length of 15 digits. > -Mark
Sorry, didn't see that email for some reason, even though it's right here in my inbox. . . Raj
On Apr 27, 2007, at 23:06 , James Edward Gray II wrote:
> On Apr 27, 2007, at 3:10 PM, anansi wrote: >> James Edward Gray II wrote: >>> On Apr 27, 2007, at 12:58 PM, Matthew Moss wrote: >>>> So is a card number like "4012 3456 7890" a valid Unknown, or an >>>> invalid Visa? >>> Visa Invalid >>> Always match the type first. >> Nope thats no Visa number but a unknown one. Visa Cards have a >> certain length (13 or 16) and if that length doesn't fit >> (Matthew's number here had just 12 digits)it's unknown :) >> otherwise the length would be obsolete don't you think? >> Both length and startingbytes have equal weight in the decision >> wether a card belongs to a known Company or not. > You are right. I didn't read well. It's Unknown. > James Edward Gray II
Do we display Valid/Invalid for unknown cards? - And by the way: 4012 3456 7890 isn't valid is it? So should that not be "invalid Unknown" or "invalid Visa"? /C
Christoffer Lern wrote: >> James Edward Gray II > Do we display Valid/Invalid for unknown cards?
We desplay unknown for unkown cards :) and valid/invalid for valid or invalid cards, the first has nothing to do with the second. Check first if it's a known one which depends on both the length and the starting bytes. Then output if it's a known or unknown one. After that, check the known or unknown number for validation and output that result. > - And by the way: 4012 3456 7890 isn't valid is it? So should that not > be "invalid Unknown" or "invalid Visa"? > /C
That's a unknown and invalid one. To be a Visa one it would need to be 13 or 15 bytes long. -- greets ( ) ( /\ .-"""-. /\ //\\/ ,,, \//\\ |/\| ,;;;;;, |/\| //\\\;-"""-;///\\ // \/ . \/ \\ (| ,-_| \ | / |_-, |) //`__\.-.-./__`\\ // /.-(() ())-.\ \\ (\ |) '---' (| /) ` (| |) ` jgs \) (/ one must still have chaos in oneself to be able to give birth to a dancing star
anansi wrote:
> That's a unknown and invalid one. To be a Visa one it would need to be > 13 or 15 bytes long.
13 or 16 of course... -- greets ( ) ( /\ .-"""-. /\ //\\/ ,,, \//\\ |/\| ,;;;;;, |/\| //\\\;-"""-;///\\ // \/ . \/ \\ (| ,-_| \ | / |_-, |) //`__\.-.-./__`\\ // /.-(() ())-.\ \\ (\ |) '---' (| /) ` (| |) ` jgs \) (/ one must still have chaos in oneself to be able to give birth to a dancing star
On Apr 28, 2007, at 7:43 AM, Christoffer Lern wrote:
> On Apr 27, 2007, at 23:06 , James Edward Gray II wrote: >> On Apr 27, 2007, at 3:10 PM, anansi wrote: >>> James Edward Gray II wrote: >>>> On Apr 27, 2007, at 12:58 PM, Matthew Moss wrote: >>>>> So is a card number like "4012 3456 7890" a valid Unknown, or >>>>> an invalid Visa? >>>> Visa Invalid >>>> Always match the type first. >>> Nope thats no Visa number but a unknown one. Visa Cards have a >>> certain length (13 or 16) and if that length doesn't fit >>> (Matthew's number here had just 12 digits)it's unknown :) >>> otherwise the length would be obsolete don't you think? >>> Both length and startingbytes have equal weight in the decision >>> wether a card belongs to a known Company or not. >> You are right. I didn't read well. It's Unknown. >> James Edward Gray II > Do we display Valid/Invalid for unknown cards? > - And by the way: 4012 3456 7890 isn't valid is it? So should that > not be "invalid Unknown" or "invalid Visa"?
I would go ahead and display Valid/Invalid normally. That way people can use the program on cards we didn't cover, as long as they conform to the standard. James Edward Gray II
On Fri, Apr 27, 2007 at 08:59:49PM +0900, Ruby Quiz wrote: > The first check people often do is to validate that the card matches a known > pattern from one of the accepted card providers. Some of these patterns are: > +============+=============+===============+ > | Card Type | Begins With | Number Length | > +============+=============+===============+ > | AMEX | 34 or 37 | 15 | > +------------+-------------+---------------+ > | Discover | 6011 | 16 | > +------------+-------------+---------------+ > | MasterCard | 51-55 | 16 | > +------------+-------------+---------------+ > | Visa | 4 | 13 or 16 | > +------------+-------------+---------------+
Wikipedia has a great chart showing all the prefixes of most known credit cards, along with lengths and overlap between cards (currently none). http://en.wikipedia.org/wiki/Credit_card_number enjoy, -jeremy -- ======================================================================== Jeremy Hinegardner jer@hinegardner.org
On Apr 27, 2007, at 7:59 AM, Ruby Quiz wrote: <snippage> > 1. Starting with the next to last digit and continuing with every > other > digit going back to the beginning of the card, double the digit > 2. Sum all doubled and untouched digits in the number > 3. If that total is a multiple of 10, the number is valid > For example, given the card number 4408 0412 3456 7893: > Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 > Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 > Step 3: 70 % 10 == 0 > Thus that card is valid.
Uh, this is probably just affecting me but.... In his example, after he doubles the second to last digit (call it d), he uses mod10 on it (9*2 = 18 %10 = 8). That is the way to get his numbers, but a) where does he say that and b) where do the 10 and 14 come from? Help me, hyperactive ruby posters! ~ Ari English is like a pseudo-random number generator - there are a bajillion rules to it, but nobody cares.
You move back to the beginning after doubling the 2nd to last. You double every other one on the way back to the beginning. The 10 is 5*2 and the 14 is 7*2 On Apr 28, 2007, at 8:04 PM, Ari Brown wrote:
> On Apr 27, 2007, at 7:59 AM, Ruby Quiz wrote: > <snippage> >> 1. Starting with the next to last digit and continuing with every >> other >> digit going back to the beginning of the card, double the digit >> 2. Sum all doubled and untouched digits in the number >> 3. If that total is a multiple of 10, the number is valid >> For example, given the card number 4408 0412 3456 7893: >> Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 >> Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 >> Step 3: 70 % 10 == 0 >> Thus that card is valid. > Uh, this is probably just affecting me but.... > In his example, after he doubles the second to last digit (call it > d), he uses mod10 on it (9*2 = 18 %10 = 8). That is the way to get > his numbers, but a) where does he say that and b) where do the 10 > and 14 come from? > Help me, hyperactive ruby posters! > ~ Ari > English is like a pseudo-random number generator - there are a > bajillion rules to it, but nobody cares.
On Apr 28, 9:04 pm, Ari Brown <a@aribrown.com> wrote:
> On Apr 27, 2007, at 7:59 AM, Ruby Quiz wrote: > > 1. Starting with the next to last digit and continuing with every > > other > > digit going back to the beginning of the card, double the digit > > 2. Sum all doubled and untouched digits in the number > > 3. If that total is a multiple of 10, the number is valid > > For example, given the card number 4408 0412 3456 7893: > > Step 1: 8 4 0 8 0 4 2 2 6 4 10 6 14 8 18 3 > > Step 2: 8+4+0+8+0+4+2+2+6+4+1+0+6+1+4+8+1+8+3 = 70 > > Step 3: 70 % 10 == 0 > > Thus that card is valid. > Uh, this is probably just affecting me but.... > In his example, after he doubles the second to last digit (call it > d), he uses mod10 on it (9*2 = 18 %10 = 8). That is the way to get > his numbers, but a) where does he say that and b) where do the 10 and > 14 come from?
The confusing part (that I didn't catch when I read it) is that step 2 is to sum all the *digits*, not the numbers. So step 1) 9 * 2 = 18 step 2) 1 + 8 He's not modding the result of the multiplication by 10, but rather adding up the resulting component digits. The same occurs with the 10 and 14 (which Philip pointed out are the result of 5*2 and 7*2, respectively).
On 4/27/07, Ruby Quiz <j@grayproductions.net> wrote: > This week's Ruby Quiz is to write a program that accepts a credit card number as > a command-line argument. The program should print the card's type (or Unknown) > as well a Valid/Invalid indication of whether or not the card passes the Luhn > algorithm.
This Ruby Quiz has been translated into Japanese. Maybe there will be more people participating. http://d.hatena.ne.jp/nappa_zzz/20070429 Harry -- http://www.kakueki.com/ruby/list.html A Look into Japanese Ruby List in English
|
 |
 |
 |
 |
|