4

我是编程语言的新手,我正在使用 PHP 和 mysql。我得到了一个在 php 中做哈希表的任务。我需要做的是,存储用户收集的项目,然后显示它。在网上做了一些研究后,我将在实现哈希表时执行以下步骤,如果我错了,请纠正我:

  1. 设置表:

    -> 用户表:uid(int[5])、username(varchar[128])、item_id(int[8]、items_id_hash(int[50])

    -> 物品表:item_id(int[5]), item_name(varchar[128]), items_id_hash(int[50])

  2. 创建散列函数(如何创建散列函数?自己创建还是从互联网获取?)将键转换为散列值,然后插入到数据库中。例如:散列 item_id = 001 成散列值 = (eg) 12345。然后插入用户表。

  3. 显示/搜索。从用户那里检索哈希值,然后将其与项目表进行比较并显示它。

问题:

  1. 我的步骤正确吗?
  2. 我在哪里可以找到一个好的 php 哈希函数?我可以使用 md5 或 sha1 或盐吗?
4

4 回答 4

4

我认为您对哈希表的想法有点[已失效]。哈希表将键分解为相似的列表。例如:基于名称第一个字母的哈希表,因此将有 26 个列表。您的哈希是名称的第一个字母,这样可以更快地搜索。

md5、sha1 用于派生散列值,用于验证数据未被篡改。它们通常有 128 位或 160 位版本。因此,它需要 X 数据并通过散列发送它以得出一个 128 位的字母数字字符串,无论它在哪里完成都应该是相同的。这通常是一个安全问题。

编辑:扩展如何派生密钥的问题。

您可以利用数据的模数来创建用于行的键。在示例数据 % X 中,X 是您想要拥有的键的总数。问题是 X 很难找到。如果您有 20 个项目,那么将 X 变为 20 是可行的,并且可以快速搜索,因为每个项目都有自己的行。但是如果你有 1000 个项目,那么做 % 1000 是不可行的。做一些像 X = 75 这样的事情会更好。

于 2009-02-12T03:05:43.103 回答
2

你有两个主要问题:

1)您要选择(打开|关闭)哈希表的哈希表范式。

2) Hashtable 可以是一个简单的数组,带有键索引和冲突情况下的数组引用。

3)你必须研究你的哈希密钥生成算法( $hash = ord($string[$i]) + ($hash << 5) - $hash; 就足够了),但你也可以选择 md5/sha . 如果您知道您的密钥空间,也许您可​​以使用 unix gperf。

这是我的哈希表实现:

<?php

/**
        A brief but simple closed hash table class.
        Jorge Niedbalski R. <jnr@niedbalski.org>
**/

class   HashTable       {

        public  $HashTable = array();
        public  $HashTableSize;

        public  function __construct($tablesize) 
        {
                if($tablesize) {
                        $this->HashTableSize = $tablesize;
                } else {
                        print "Unknown file size\n";
                        return -1;
                }
        }

        public  function __destruct() 
        {
                unset($this->HashTable);
        }

        public  function  generate_bucket($string) 
        {
                for($i=0; $i <= strlen($string); $i++) {
                        $hash = ord($string[$i]) + ($hash << 5) - $hash;
                }
                print "".$this->HashTableSize."\n";
                return($hash%$this->HashTableSize);
        }
    public  function  add($string, $associated_array)
        {
                  $bucket = $this->generate_bucket($string);

                  $tmp_array = array();
                  $tmp_array['string'] = $string;
                  $tmp_array['assoc_array'] = $associated_array;                

                  if(!isset($this->HashTable[$bucket])) {
                                $this->HashTable[$bucket] = $tmp_array;
                  } else {
                        if(is_array($this->HashTable[$bucket])) {
                                array_push($this->HashTable[$bucket], $tmp_array);
                        } else {
                                $tmp = $this->HashTable[$bucket];
                                $this->HashTable[$bucket] = array();
                                array_push($this->HashTable[$bucket], $tmp);
                                array_push($this->HashTable[$bucket], $tmp_array);
                        }
                }

        }

        public  function  delete($string, $attrname, $attrvalue) 
        {       
                $bucket = $this->generate_bucket($string);

                if(is_null($this->HashTable[$bucket])) {
                                return -1;
                } else {
                        if(is_array($this->HashTable[$bucket])) {
                                for($x = 0; $x <= sizeof($this->HashTable[$bucket]); $x++) {
                                        if(($this->HashTable[$bucket][$x]['string'] == $string) && ($this->HashTable[$bucket][$x]['.$attrname.'] == $attrvalue)) {
                                                unset($this->HashTable[$bucket][$x]);   
                                        }
                                }
    } else {
                                unset($this->HashTable[$bucket][$x]);
                        }
                }       
                /** everything is OK **/                        
                return 0;
        }


        public  function  search($string) 
        {
                $resultArray = array();

                $bucket = $this->generate_bucket($string);

                if(is_null($this->HashTable[$bucket])) {
                        return -1;
                } else {
                        if(is_array($this->HashTable[$bucket])) {
                                for($x = 0; $x <= sizeof($this->HashTable[$bucket]); $x++) {
                                        if(strcmp($this->HashTable[$bucket][$x]['string'], $string) == 0) {
                                                array_push($resultArray,$this->HashTable[$bucket][$x]);
                                        }
                                 }
                        } else {
                                array_push($resultArray,$this->HashTable[$bucket]);
                        }
                }

                return($resultArray);
        }
}

        $hash = new HashTable(16);

        $arr = array('nombre' => "jorge niedbalski");

        $hash->add("astroza", $arr);
        $hash->add("astrozas", $arr);

        print_r($hash->search("astroza"));

?>
于 2009-02-12T03:11:09.130 回答
1

你的意思是一个哈希值(你存储在一个表中),而不是一个哈希表?

我看不出如何以有用的方式将这些数据存储在哈希表中。(Suroots 回答解释了哈希表)。

要使用 MD5 创建哈希值,请尝试

hash('md5', '要散列的字符串');

有关更多详细信息,请参见http://au.php.net/function.hash

于 2009-02-12T03:14:24.910 回答
1

roa3

该代码没有使用任何持久数据存储后端,您可以简单地对其进行扩展以添加 mysql 支持。

您必须在关系数据库中使用 one_to_many 关系(桶、条目)来实现这一点。

想想如何扩展这个基类。

祝你好运

于 2009-02-12T04:23:47.940 回答