paralleldrive / cuid

Collision-resistant ids optimized for horizontal scaling and performance.
Other
3.44k stars 123 forks source link

Simple and effective CUID regex? #118

Closed brikou closed 6 years ago

brikou commented 6 years ago

I've already check isCuid method, but this fn only check that it is a string starting by "c"

Do you know a simple and effective way to check that given string look like a real CUID?

Thanks for your great lib :+1:

MarkHerhold commented 6 years ago

See https://github.com/ericelliott/cuid/issues/88

Basically there are no other guarantees.

brikou commented 6 years ago

thanks @MarkHerhold

supermacro commented 3 years ago

Basically there are no other guarantees.

There is definitely a defined set of values that a cuid is comprised of. I'm re-posting my screenshot here from #88 to help others in case they're looking for something a bit more definitive.

Screen Shot 2021-03-24 at 7 50 53 PM

So based on the above you could have something like this:

const CODES = {
  a: 97,
  zero: 48,
}

// numerical char codes range from 48 -> 48 + 9
const NUMBERS_CHAR_CODES = Array(10).fill(null).map((_, idx) => idx + CODES.zero)

// lowercase alphabet codes
const LOWERCASE_LETTERS_CHAR_CODES = Array(26).fill(null).map((_, idx) => idx + CODES.a)

const VALID_CUID_CHAR_CODES = [ ...NUMBERS_CHAR_CODES, ...LOWERCASE_LETTERS_CHAR_CODES ]

const containsOnlyValidCuidValues = (val: string): boolean => {
  // remove 'c' char
  const tail = val.substr(1)

  return tail.split('').every(
    (char) => VALID_CUID_CHAR_CODES.includes(char.charCodeAt(0))
  )
}

// https://github.com/ericelliott/cuid/issues/88#issuecomment-339848922
const isCuid = (val: unknown): val is string =>
  typeof val === 'string' &&
  val.charAt(0) === 'c' &&
  val.length > 7 &&
  containsOnlyValidCuidValues(val)
iki commented 2 years ago
// export { isCuid } from 'cuid';

// NOTE: Future cuid may change, they are only guaranteed to start with `c` and have at least 7 characters
// See https://github.com/paralleldrive/cuid/issues/88#issuecomment-339848922
// Having generation under control, we extend the check to lowercase+digits charset and 25 characters length 
const cuidRegex = /^c[a-z0-9]{24}$/;
export const isCuid = (value: string) => cuidRegex.test(value);
ericelliott commented 2 years ago

I do not recommend using a regex to validate cuids.