refactor canonical_string function