tags:

views:

370

answers:

6

I needed a unique internal int to use that would represent several random content types that I couldn't hard code as class constants or config options. Yet I didn't want to refer to "2" when I could use the easier to follow term "post". So though up the a way to get a INT value from a string which seems to work fairly collision free for a couple items.

Is there a way to do this in php rather than what I built?

$strings = array('post', 'comment', 'blog', 'article', 'forum', 'news', 'page');

foreach( $strings as $string ) {

    print $string . ' = ';

    $string = str_split($string);
    $sum = 0;
    foreach( $string as $char ) {
     $sum += ord($char);
    }

    var_dump( $sum );

    print '<br />';
}

This has nothing to do with user input so don't worry about the obvious flaws in the design.

:EDIT:

I need a numeric index for storing in a database for fast look ups. i.e. to tell "posts" from "articles" or "news". Yet I don't know what those 1-8 types of content will be called so I can't hard code those as constants in the app. Therefore, the best thing I could figure would be to create a numeric version of each word (which means checking to make sure two words don't sum up to the same number).

If this were for a system that would have more than 8 words then this method is doomed to failure do to the high probability of sum collisions. Also, if I had a choice in knowing what words would be used then this would also be terrible design as class constants would work much better.

A: 
$strings = array('post' => 0, 'comment' => 1, 'blog' => 2, 'article' => 3, 'forum' => 4, 'news' => 5, 'page' => 6);

$s = 'comment';
$s_as_int = $strings[$s];
JasonWoof
"Yet I didn't want to refer to "2" when I could use the easier to follow term "post""
yoda
yeah, you can use 'post' all you want, then when you need the integer $strings['post']
JasonWoof
Basically, what I'm suggesting here, is that you can use a dictionary to map the strings to ints. you could also just use a regular array, and instead of $strings['post'] to convert to int, you use array_search('post', $strings). when you add new words that you need ints for, you can just push them onto the end of $strings
JasonWoof
I can only make vague guesses as to what might work well, since you haven't said what you're trying to do.
JasonWoof
If you want some function that will take any string, and give you a unique identifier for it, you'd be looking for a hash function. A strong hash function (ie one where you won't see a collision) such as md5 or sha1 will do this well, but the identifier will be bigger than an int (16-40 bytes)
JasonWoof
All of this is way too much work to create an enum type. JasonWoof's first suggestion of just using the string ("post","news", etc.) all ya want would work swell. Combine it with MySQL's ENUM type and you're set for success.
Good Time Tribe
+1  A: 

You can't use a single unique integer, since two different integers have a very high chance of adding up to the same result. 3+3 = 6; 2+2+2 = 6;

You are better off using a non-reversable hash. This is more of a unique sequence, then the sum of the sequence.

ie: md5(), sha1(), sha256() etc.

You can also use PHP5's spl_object_hash() which assigns a unique hash to every Object. http://us3.php.net/manual/en/function.spl-object-hash.php

ps: if you needed integers, you'd be using really large integers. Thus you can just concatenate the integers in your example, instead of adding them.

bucabay
A: 
<?php
$strings = array('post', 'comment', 'blog', 'article', 'forum', 'news', 'page');

foreach( $strings as $string )
{
    echo $string . ' = ' . base_convert(md5($string), 16, 10) . '<br />';
}
?>
w35l3y
+1  A: 

I think you're looking to achieve an analog to an "enumerated type" like in C, C++, C#, Pascal, Java, etc. You don't mention what type of database you are using, but MySQL makes this easy to accomplish by using the ENUM type.

Good Time Tribe
True, if I was only using MySQL this would be a good option.
Xeoncross
+1  A: 

You could use crc32, which is a checksumming function that simply returns a 4 byte integer.

ryeguy
Thats awesome, nothing could be simpler.
Xeoncross
A: 

Couldn't you just array_flip() or array_search() your dictionary?

Or store your dictionary in the database as well in another table called dictionary that looks something like this (MySQL)

CREATE TABLE `dictionary` (
  `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `word` VARCHAR(25),
  UNIQUE `word` (`word`)
)
gnarf
Not really, I don't have an array of words neither do I even know what they will be. Developers after me will be creating a few of them.
Xeoncross