generalize id generation