Per the ID Field Type Docs:
ID fields in the Salesforce user interface contain 15-character,
base-62, case-sensitive strings. Each of the 15 characters can be a
numeric digit (0-9), a lowercase letter (a-z), or an uppercase letter
(A-Z). Two unique IDs may only be different by a change in case.
So, any 15 digit alphanumeric value is valid. A simple REGEX can validate this.
For an 18 digit ID, the last 3 digits are a "calculated suffix" of the first 15 characters case sensitivity :
as referenced on 15 or 18 Character IDs in Salesforce.com as well as numerous other sites. We can use this logic, to verify if the 15 digit substring + the "calculated suffix" matches the full 18 digit value.
Piecing all of this together, gives you the following validation rule:
REGEX(Polymorphic_ID__c, '^[a-zA-Z0-9]+$'), /** must be alphanumeric **/
LEN(Polymorphic_ID__c) == 18,
CASESAFEID(LEFT(Polymorphic_ID__c, 15)) != Polymorphic_ID__c, /** if its 18 characters, verify that the 3 digit calculated suffix is valid **/
IF (LEN(Polymorphic_ID__c) == 15, /** any 15 digit alphanumeric is valid **/
I've tested this on a number of scenarios, and it appears to check out. One thing to note, per the docs "00100000000myidAAA" is a valid ID, and it passes the "calculated suffix" test, so this validation rule isn't preventing that.