I don't know these guys but it looks like a ready hardware part of the solution:http://www.phidgets.com/products.php?product_id=1102_0
OTOH, knowing that black and white reflect differently you can try making your own sensor and yes, tape a bar code under each car.
Consider using white stripes (more reflective) for data and black stripes as reference widths. A zero would be a narrow white stripe and a one would be 3x as wide a white strip. The black stripes would all be narrow. You would be reading perhaps 10,000x a second, keep count of how many reads the last black stripe was and if the next white strip is less than 1.5x as many then it's a zero bit but if 2.5x or more then it's a one bit.
Then start your data sector with an attention section of 8 narrow b/w stripes followed by a wide black stripe, the next white stripe begins your data.
The boffo setup would read the same no matter which direction the train is going, attention section at both ends and each car's ID being symmetric. You could get away with 2 number / 4 white stripe codes that would read 0000 0000, 0001 1000, 0010 0100, etc.
I did kind of adapt an idea from Mitsubishi Labs there, but it's kind of adapted from old telegraph Morse code methods that had to be invented because humans don't tap keys with clock-like precision (long story short) so I doubt there will be a patent battle if you go to market.
Besides, I added the bit about using the black stripes for reference, Mitsubishi just used relative numbers of flash reads of data alone to know dit from dah.
The at least twice borrowed idea being that no data is not a data zero. That was used before computers, even the 1880's electro-mechanical type (hole or not being the data). IIRC the words are 'prior art'.