Auto-increment alphanumeric characters in PHP

LincLinc OwnerDetroit Icrontian
edited April 2009 in Internet & Media
Anyone know how to auto-increment alphanumeric characters for a URL-shortener in PHP?

Instead of counting up from zero, I'd want it to count up from 0-9 and then a-z. Then it would be 00-09 to 0a-0z, and then to 10-19 to 1a-1z, and so on.

Comments

  • MiracleManSMiracleManS Chambersburg, PA Icrontian
    edited April 2009
    BIT-WISE ASCII ENCODES!?!!!!!!


    Edit: Now to be serious...

    Convert the string to a decimal, add one, then turn it back into ascii...
  • pragtasticpragtastic Alexandria, VA Icrontian
    edited April 2009
    MMS: What happens when you add 1 to z? You're gonna go off the end of your range and get some ascii value that you don't want.

    This might be the long/tedious route, but probably how I'd go about it if you can't find something out there for this already:

    Setup a mapping that correlates 0-9a-z to 0-35, maybe in a method that takes a single character and returns the int (sadly this would probably be a 36 case switch statement).
    Then break your alphanumeric string into single character and load those into an array. Try to increment the last element of the array by 1 and do a mod operation on the sum by 36 ( newVal = (val +1) % 36). If your newVal is then a 0 (you rolled over), then you need to go back another element in the array and repeat the process. If you roll over all the values in the array, then you tack a 0 on to all the other 0's in the array. Once the operation is done, collect your integers, run them through the mapping in reverse and concat them back into a string.
  • pragtasticpragtastic Alexandria, VA Icrontian
    edited April 2009
    Other thoughts...

    I presume you're using 0-9a-z because it'll keep the url smaller for a longer duration (versus something like a simple 0-9 system). If you're going for something that, have you considered using UpperCase letters as well, so 0-9a-zA-Z? Giving 62 characters to work with instead of 36.
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    don't know how to use php, but:

    use an int counter;
    digone   = counter (mod) 36^5
    digtwo   = counter (mod) 36^4
    digthree = counter (mod) 36^3
    digfour  = counter (mod) 36^2
    digfive  = counter (mod) 36
    
    char out = convertToChar(input) {
     out = 0;
     if(input) < 10 {
        out = input + 48;
     } else {
        out = input + 87;
     }
    }
    

    then concat all the individual chars
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    and you could totally do that in some sort of cool for loop.
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    and if you wanted to restrict yourself to 32 chars, you could do it with some bit-shifting, rather than mod operations.


    ttttttt-riple post
  • LincLinc Owner Detroit Icrontian
    edited April 2009
    Yeah, I'll probably do something like MiracleMan or prag described; split it up, convert to a numeric representation, increment, boundary check it, convert back to the equivalent alphanumerics, and concat back together. Ugh.
    pragtastic wrote:
    have you considered using UpperCase letters as well, so 0-9a-zA-Z?
    Domain names are case-insensitive. While you can make the rest of the URL case-sensitive, it's not expected behavior. People expect, for instance, that http://twitter.com/Icrontic and http://twitter.com/icrontic are the same thing. The potential confusion isn't worth the saved characters.
    shwaip wrote:
    don't know how to use php, but:
    use an int counter;
    then concat all the individual chars
    You done gone lost me. :-/

    //edit: shwaip, PHP is super-low-level; there's no strict variable typing, required declarations, or playing with bits. I can't even remember what mod does; I only had an intro C++ course (I assume that's what that was).
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    Also, I ninja edited the code a little.

    mod (%) is basically remainder. 1234 % 1000 = 234;

    i re-wrote code below in a better way.

    and so on.

    the chr() function converts the ascii value to a character
  • pragtasticpragtastic Alexandria, VA Icrontian
    edited April 2009
    Lincoln wrote:
    //edit: shwaip, PHP is super-low-level; there's no strict variable typing, required declarations, or playing with bits. I can't even remember what mod does; I only had an intro C++ course (I assume that's what that was).

    I would say loose typing makes a language more high-level than low-level ;)
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    wow my code is wrong - new code:

    [php]

    for($counter=0; $counter < HUEG; $counter++){ #this would be the global_index for all your articles
    $shortURL ="";
    $tmp_count = $counter;
    for($i=URL_LEN; $i > 0; $i--){ #URL_LEN is the desired length of url
    $tmp = floor($tmp_count/(36^$i));
    $tmp_count -= $tmp*(36^$i);
    if($tmp < 10) {
    $shortURL .= chr($tmp + 48);
    } else {
    $shortURL .= chr($tmp + 87);
    }
    }
    }

    [/php]
  • pragtasticpragtastic Alexandria, VA Icrontian
    edited April 2009
    shwaip: nice use of powers(36^$i), I wouldn't have thought of that.
  • MiracleManSMiracleManS Chambersburg, PA Icrontian
    edited April 2009
    pragtastic wrote:
    MMS: What happens when you add 1 to z? You're gonna go off the end of your range and get some ascii value that you don't want.

    I didn't know I had to prescribe the ENTIRE idea and code it for him :tongue:
  • pragtasticpragtastic Alexandria, VA Icrontian
    edited April 2009
    shwaip did the heavy lifting :P
  • LincLinc Owner Detroit Icrontian
    edited April 2009
    OK, but there won't be a static URL length; it'll grow with necessity (starting at 1 character), not stay fixed at a particular length.

    So then 36^URL_LEN >= the integer key (HUEG), right? Then I could run this bit before yours:

    [php]
    $a = HUEG;
    $URL_LEN = 1;
    while ( $a > 36 ) {
    $a = $a/36;
    $URL_LEN++;
    }[/php]
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited April 2009
    a few examples - obviously, you'd increment by 1 for IC articles/links.:
    http://students.washington.edu/hanusaem/test.php

    source:
    http://students.washington.edu/hanusaem/test.txt
  • LincLinc Owner Detroit Icrontian
    1. This is still powering our link shorteners.
    2. Wow was I ever a newb.
    midgaErrorNullTurnip
  • shwaipshwaip bluffin' with my muffin Icrontian
    Lincoln said:

    1. This is still powering our link shorteners.
    2. Wow was I ever a newb.

    *brofist*
  • BobbyDigiBobbyDigi ? R U #Hats ! TX Icrontian
    4+ year Bompz necro. Pro shit.

    -Digi
Sign In or Register to comment.