I don't believe that validation rules allow for dynamic messages, so that wouldn't be an option.
In code, probably the easiest way to get a field's position is something like.
XPathNodeIterator previousRows = e.Site.Select("../preceding-sibling::my:repeatingGroup", NamespaceManager);
int position = previousRows.Count + 1;
You may need to add or remove ../s to the path depending on the relative path from e.Site to the repeating group.