Generate a shortened unique short code like Bit.ly

2,351 views
Skip to first unread message

Mike Kingery

unread,
Feb 7, 2014, 12:24:52 PM2/7/14
to tacfug
I'm looking to generate short, unique strings for use just like Bit.ly to replace long GUID and encoded/encrypted strings that a system generates. Does anyone know of a method to generate something like this:
G5jN3yS

Instead of this:
A24AB0CE-3CC2-4730-85E9-AEC7D4B4F519


Roger Austin

unread,
Feb 7, 2014, 12:27:23 PM2/7/14
to tac...@googlegroups.com
You might want to check with Tim Cunningham to did the cfml shortener
thingy.

--
LinkedIn: http://www.linkedin.com/pub/8/a4/60
Twitter: http://twitter.com/RogerTheGeek
Blog: http://rogerthegeek.wordpress.com/

Anant Pradhan

unread,
Feb 7, 2014, 12:32:08 PM2/7/14
to tac...@googlegroups.com

I imagine you could write a function that returns a random 6 character alpha-numeric string for any given input. Store the input and the corresponding string in a table. Make sure any generated string has not been used before.

 

Anant

--
Upcoming events: http://www.meetup.com/Triangle-Area-ColdFusion-Users-Group/
Follow us on Twitter: @tacfug
---
You received this message because you are subscribed to the Google Groups "TACFUG" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tacfug+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Dan Wilson

unread,
Feb 7, 2014, 12:39:55 PM2/7/14
to tac...@googlegroups.com
this is pretty straightforward:

http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener

Mike Kingery wrote:
--
Upcoming events:
http://www.meetup.com/Triangle-Area-ColdFusion-Users-Group/
Follow us on Twitter: @tacfug
---
You received this message because you are subscribed to the Google
Groups "TACFUG" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to tacfug+unsubscribe@googlegroups. com.

Mike Kingery

unread,
Feb 7, 2014, 1:05:51 PM2/7/14
to tac...@googlegroups.com
Forgot to note that I'm looking for something non-sequential. Basically the equivalent of CreateUUID() but shorter. It doesn't have to be reversible. This eliminates the option below and the one from Tim Cunningham. I'm suspecting that this is just not a easy task as combing random and short without producing conflicts is not going to happen easily. 

I could try to hash/shorten the UUID to make it shorter by using an expanded character set but I'm not sure it's worth it if it won't drastically reduce the number of characters.

Alternatively I suppose I could call the Bit.ly API and use their strings as they're going to be relatively random and unique. It's a more ideal result but I'd feel bad about using their servers for that and/or the external requests.

- Mike 


From: Dan Wilson <sipa...@gmail.com>
To: tac...@googlegroups.com
Sent: Friday, February 7, 2014 12:39 PM
Subject: Re: [tacfug] Generate a shortened unique short code like Bit.ly

To unsubscribe from this group and stop receiving emails from it, send an email to tacfug+un...@googlegroups.com.

Dan Wilson

unread,
Feb 7, 2014, 1:24:22 PM2/7/14
to tac...@googlegroups.com
Random, short and unique are opposite goals. You need to base this off something that will be unique, then encode it to something that shortens it. If you know you'll only have 10,000 of these, then that makes it easier.

If you can keep a counter somewhere to drive function, cool. You'll need a way to bottleneck access to the counter, to ensure uniqueness.
If you use something non-local, like the current number of milliseconds since epoch, you'll have to ensure 2 different systems don't hit this at the same time, or (more commonly), two systems don't have slightly different times.

I worked on something like this a while back, and the net result is, you need to have a counter of some kind that can be trusted, then encode the counter to something that'll shorten it up, while using acceptable characters.

Here's something that might help:

99999 = 5 digits (1-9) and not quite 100,000 values
A9BLZ = 5 characters of zero through Z (all upper case) has 60,466,176  values
A9tz8 = 5 characters of zero through z (mixed case) has 916,132,832 values

Now, something to keep in mind is, in certain fonts, some numbers can look like some letters (1 and l, 0 and O) so if this is something that a person would hand-type, you'll want to deal with this.






Friday, February 07, 2014 1:05 PM
Friday, February 07, 2014 12:39 PM
this is pretty straightforward:

http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener

Mike Kingery wrote:
Friday, February 07, 2014 12:24 PM
I'm looking to generate short, unique strings for use just like Bit.ly to replace long GUID and encoded/encrypted strings that a system generates. Does anyone know of a method to generate something like this:
G5jN3yS

Instead of this:
A24AB0CE-3CC2-4730-85E9-AEC7D4B4F519


--
Upcoming events: http://www.meetup.com/Triangle-Area-ColdFusion-Users-Group/
Follow us on Twitter: @tacfug
---
You received this message because you are subscribed to the Google Groups "TACFUG" group.

Denard Springle

unread,
Feb 8, 2014, 3:23:37 AM2/8/14
to tac...@googlegroups.com, Mike Kingery
Something along these lines, perhaps?

<cffunction name="getShortURL" access="public" returntype="string" output="false" hint="I return a random, verified short URL.">
   
    <cfset var thisKey = getKey() />
    <cfset var isValidKey = checkKey(thisKey) />
   
    <cfloop condition="#NOT isValidKey#">
        <cfset thisKey = getKey() />
        <cfset isValidKey = checkKey(thisKey) />
    </cfloop>
   
    <cfreturn thisKey />
</cffunction>

<cffunction name="getKey" access="private" returntype="string" output="false" hint="I return a random key to use for the URL.">
    <cfargument name="keyLength" type="numeric" required="false" default="6" hint="I am the length of the random key you wish to return.">
   
    <cfset var keySeed = Hash(CreateUUID(),'SHA-384') />
    <cfset var thisKey = Mid(keySeed,RandRange(1,Len(keySeed)-(ARGUMENTS.keyLength+1)),ARGUMENTS.keyLength) />
   
    <cfreturn thisKey />
</cffunction>

<cffunction name="checkKey" access="private" returntype="boolean" output="false" hint="I check a passed key and return true or false.">
    <cfargument name="checkKey" type="string" required="true" hint="I am the key to check for the existence of." />
   
    <cfset var qGetKey = '' />
   
    <cfquery name="qGetKey">
        SELECT [column]
        FROM [table]
        WHERE [column] = <cfqueryparam value="#ARGUMENTS.checkKey#" cfsqltype="cf_sql_varchar" />
    </cfquery>
   
    <cfif qGetKey.RecordCount>
        <cfreturn false />
    <cfelse>
        <cfreturn true />
    </cfif>
</cffunction>       

Repalce [table] and [column[ with appropriate table and column from your database, modify as needed.

Instead of using the Hash() function, you could also have a list of uppercase, lowercase and numbers (e.g. A-Za-Z0-9) that you do a random mid() for, looped over keyLength number of times, ala:

<cfset var alphaNum = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,0,1,2,3,4,5,6,7,8,9' />
<cfset var thisKey = '' />
<cfset var iX = 0 />

<cfloop from="1" to="#ARGUMENTS.keyLength#" index="iX">
    <cfset thisKey = thisKey & LisGetAt(alphaNum,RandRange(1,Len(alphaNum))) />
</cfloop>

HTH

-- Denny

Denard Springle

unread,
Feb 8, 2014, 3:29:13 AM2/8/14
to tac...@googlegroups.com, Mike Kingery

<cfset var alphaNum = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9' />

Sorry... 3:30am here... a bit punchy and forgot the rest of the alphabet for lowercase ;P


-- Denny

On Friday, February 7, 2014 12:24:52 PM UTC-5, Mike wrote:

Denard Springle

unread,
Feb 8, 2014, 3:38:39 AM2/8/14
to tac...@googlegroups.com, Mike Kingery
I really ought not write code at 3:30am lol...

One more change:

<cfset thisKey = thisKey & LisGetAt(alphaNum,RandRange(1,ListLen(alphaNum))) />

-- Denny

Denard Springle

unread,
Feb 8, 2014, 7:19:29 AM2/8/14
to tac...@googlegroups.com, Mike Kingery
Compiled into an easily consumed package:

https://github.com/teamcfadvance/IrreversibleURLShortener

Mike Kingery

unread,
Feb 11, 2014, 9:35:55 AM2/11/14
to tac...@googlegroups.com
Fantastic! I forked it and made some updates based on my testing.

Before you posted this response I had been thinking something along the lines of encoding the sequential ID and inserting random numbers/letters in every other field. Again, not an uncrackable code or anything but obfusticated enough for my purposes.

- Mike


From: Denard Springle <denard....@gmail.com>
To: tac...@googlegroups.com
Cc: Mike Kingery <talle...@yahoo.com>
Sent: Saturday, February 8, 2014 7:19 AM
Subject: [tacfug] Re: Generate a shortened unique short code like Bit.ly

Compiled into an easily consumed package:

https://github.com/teamcfadvance/IrreversibleURLShortener


Denard Springle

unread,
Feb 11, 2014, 9:05:19 PM2/11/14
to tac...@googlegroups.com, Mike Kingery
Hey Mike,

   Glad you found it helpful, and thank you for the second set of eyes and sanity check of the code on GitHub... I've merged your fixes into the master branch.:)

-- Denny
Reply all
Reply to author
Forward
0 new messages