开发者

How to generate unique (short) URL folder name on the fly...like Bit.ly

开发者 https://www.devze.com 2023-02-24 02:50 出处:网络
I\'m creating an application which开发者_Go百科 will create a large number of folders on a web server, with files inside of them.

I'm creating an application which开发者_Go百科 will create a large number of folders on a web server, with files inside of them.

I need the folder name to be unique. I can easily do this with a GUID, but I want something more user friendly. It doesn't need to be speakable by users, but should be short and standard characters (alphas is best).

In short: i'm looking to do something like Bit.ly does with their unique names:

www.mydomain.com/ABCDEF

Is there a good reference on how to do this? My platform will be .NET/C#, but ok with any help, references, links, etc on the general concept, or any overall advice to solve this task.


Start at 1. Increment to 2, 3, 4, 5, 6, 7,

8, 9, a, b...

A, B, C...

X, Y, Z, 10, 11, 12, ... 1a, 1b,

You get the idea.

You have a synchronized global int/long "next id" and represent it in base 62 (numbers, lowercase, caps) or base 36 or something.


I'm assuming that you know how to use your web server's redirect capabilities. If you need help, just comment :).

The way I would do it would be generating a random integer (between the integer values of 'a' and 'z'); converting it into a char; appending it to a string; and repeating until we reach the needed length. If it generates a value already in the database, repeat the process. If it was unique, store it in the database with the name of the actual location and the name of the alias.

This is a bit hack-like because it assumes that 'a' through 'z' are actually in sequence in their integer values.

Best I could think of :(.


In Perl, without modules so you can translate more easly.

sub convert_to_base {
    my ($n, $b) = @_;
    my @digits;
    while ($n) {
        my $digits = $n % $b;
        unshift @digits, $digit;
        $n = ($n - $digit) / $b;
    }
    unshift @digits, 0 if !@digits;
    return @digits;
}

# Whatever characters you want to use.
my @digit_set = ( '0'..'9', 'a'..'z', 'A'..'Z' );

# The id of the record in the database,
# or one more than the last id you generated.
my $id = 1;

my $converted =
    join '',
    map { $digit_set[$_] }
    convert_to_base($id, 0+@digits_set);


I needed something similar to what you're trying to accomplish. I retooled my code to generate folders so try this. It's setup for a console app, but you can use it in a website also.

    private static void genRandomFolders()
    {
        string basepath = "C:\\Users\\{username here}\\Desktop\\";
        int count = 5;
        int length = 8;

        List<string> codes = new List<string>();
        int total = 0;
        int i = count;
        Random rnd = new Random();
        while (i-- > 0)
        {
            string code = RandomString(rnd, length);
            if (!codes.Exists(delegate(string c) { return c.ToLower() == code.ToLower(); }))
            {
                //Create directory here
                System.IO.Directory.CreateDirectory(basepath + code);
            }
            total++;
            if (total % 100 == 0)
                Console.WriteLine("Generated " + total.ToString() + " random folders...");
        }

        Console.WriteLine();
        Console.WriteLine("Generated " + total.ToString() + " total random folders.");
    }
    public static string RandomString(Random r, int len)
    {
        //string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; //uppercase only
        //string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; //All
        string str = "abcdefghjkmnpqrstuvwxyz123456789"; //Lowercase only
        StringBuilder sb = new StringBuilder(); 
        while ((len--) > 0)
            sb.Append(str[(int)(r.NextDouble() * str.Length)]);
        return sb.ToString(); 
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号