我想使用便携式 PHP 密码散列框架来散列密码。但我发现它的演示不使用盐来散列密码。但是它使用了一个虚拟盐来检查密码,我觉得这很奇怪,我根本不明白这个想法,
$dummy_salt = '$2a$08$1234567890123456789012';
if (isset($dummy_salt) && strlen($hash) < 20)
$hash = $dummy_salt;
Run Code Online (Sandbox Code Playgroud)
我想知道,如果我想使用可以生成唯一盐并将其存储在我的数据库中的每个用户的约定方法,我如何使用便携式 PHP 密码哈希框架来生成盐?
这是我用来散列密码的函数,但有人告诉我 sha512 与 sha1 有相同的问题,明智地信任像便携式 PHP 密码散列框架这样的专家,
function hash_sha512($phrase,&$salt = null)
{
//$pepper = '!@#$%^&*()_+=-{}][;";/?<>.,';
if ($salt == '')
{
$salt = substr(hash('sha512',uniqid(rand(), true).PEPPER_KEY.microtime()), 0, SALT_LENGTH);
}
else
{
$salt = substr($salt, 0, SALT_LENGTH);
}
return hash('sha512',$salt.PEPPER_KEY.$phrase);
}
Run Code Online (Sandbox Code Playgroud)
如果您有任何想法,请告诉我。谢谢。
我在面向对象的上下文中读过有关对象标识的文章.其中说"你创建的每个对象都有自己独特的身份".但我对以下代码感到困惑.
String str="Hello";
String str1="Hello";
System.out.println(str.hashCode()); //69609650
System.out.println(str1.hashCode()); //69609650
System.out.println(System.identityHashCode(str));//19313225
System.out.println(System.identityHashCode(str1));//19313225
Run Code Online (Sandbox Code Playgroud)
str和str1的哈希码和identityhashcode是相同的.如果我理解错了,请纠正我.
另外hashcode()和system.identityhashcode()之间有什么区别
如果同一类的两个对象在 Java 中具有相同的 hashCode,那么它们将如何存储在HashMap/ 中HashTable?哈希码和内存地址的实际架构是什么。hashCode 驻留在内存中的什么位置?
例子:有一个类A。创建对象时a1,a2它们将代表一些内存地址,但我每次都覆盖了哈希码。当我阅读一篇文章时,我发现 hashcode 函数从内存地址生成一个 hashcode。这意味着如果哈希码相同,内存地址将相同。请解开我的疑惑。
public class A {
@Override
public int hashCode() {
return 1;
}
public static void main(String args[]) {
A a1 = new A();
A a2 = new A();
System.out.println(a1.hashCode());
System.out.println(a2.hashCode());
}
}
Run Code Online (Sandbox Code Playgroud) public class VO {
public int hashcode()
{
return 0;
}
public boolean equals(Object obj)
{
return true;
}
public static void main(String args[])
{
VO vo1 = new VO();
VO vo2 = new VO();
Map<VO,Integer> map = new HashMap<VO, Integer>();
map.put(vo1, 1);
map.put(vo2, 1);
System.out.println(map.size());
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:2
但据我所知,输出为1.
当我在地图中放置一个元素时,它将检查密钥的哈希码,如果该哈希码相同,那么它将检查equals.如果两个方法返回相同,它将覆盖先前的值.
在我的情况下,两个方法都是(hashcode和equals)返回0和true.So最后在map中必须有一个元素.但是这里我的大小为2.
可能是什么原因.谢谢...
我有一个带有最终String的类作为唯一ID.当然我想重写equals所以比较只基于ID.那么只返回ID的哈希码是正确的做法,如下所示?
class ItemSpec{
final String name;
...
@Override
public boolean equals(Object o){
if(o != null && o instanceof ItemSpec){
return name.equalsIgnoreCase(((ItemSpec)o).name);
} else{
return false;
}
}
@Override
public int hashCode(){
if(name == null){
return 0;
} else{
return name.hashCode();
}
}
}
Run Code Online (Sandbox Code Playgroud) spl_object_hash()在这种情况下,我正在了解并且不太了解幕后的内容:
$obj = new stdClass;
$id1 = spl_object_hash($obj);
$id2 = spl_object_hash(new stdClass);
echo $id1.'<br>'.$id2;
Run Code Online (Sandbox Code Playgroud)
一季度。为什么$id1 !== $id2?
在参考资料中:
当一个对象被销毁时,它的散列值可能会被其他对象重用。
Q.2 是否有与该声明相关的内容?还是我错过了其他东西?
我正在尝试散列一个字符串,我从我的教科书中得到了代码。
这是代码:
int hash(char *str) {
int i, sum;
for (sum = 0; i = 0; str[i] != '\0'; i++)
sum += (int) str[i];
return sum % MODVAL;
}
Run Code Online (Sandbox Code Playgroud)
给我错误的代码是 str[i] != '\0';
我有一个与 java.lang.Object 中关于 hashCode 方法的广泛讨论主题相关的问题。只是有什么理由为什么我应该在某些用例中从 返回一个常量值hashCode()?
public int hashCode()
{
return 3;
}
Run Code Online (Sandbox Code Playgroud)
如果您找到一些直接回答我的问题的文章或 SO 线程,我将不胜感激。坦白说我做不到。
我的想法:
从docs.oracle.com 对象 hashCode()(我知道在 SO 中多次引用):
如果根据 equals(java.lang.Object) 方法两个对象不相等,则不需要对这两个对象中的每一个调用 hashCode 方法必须产生不同的整数结果。但是,程序员应该意识到为不相等的对象生成不同的整数结果可能会提高哈希表的性能。”
所以理论上hashCode()可以返回一个常数值。在我的想象和我读过的内容中,当使用例如HashMap. 举个例子,假设 1000 个元素将被放置在完全相同的哈希桶中(换句话说,将有 1000 次冲突),并在错误的情况下找到特定的元素,即必须迭代 1000 个元素。然后它将执行类似于LinkedList收集(如果我错了请纠正我)。
基于上述,hashCode()可以返回一个常量值,但它会破坏使用hash...集合获得的性能。那么在某些特定示例中这样做是否有意义?
编辑:我发现了一个hashCode基于 Vlad 的 Mihalcea 文章的具有常量方法的特定示例:How to implement equals and hashCode using JPA entity identifier , (Hibernate)。HashCode 在实体状态转换之间有所不同,因此它应该返回常量值。引自文章:
当实体第一次存储在 Set 中时,标识符为空。实体持久化后,标识符被分配给自动生成的值,因此 hashCode 不同。因此,实体在持久化后无法在 Set 中找到。
所以有一个实际的例子,但正如它以性能为代价所指出的那样。如果除了entity …
这是输入。
public static void main(String[] args){
StringBuilder builder = new StringBuilder("hello");
printBuilder(builder);
// append
builder.append(" everyone");
printBuilder(builder);
builder.append(", what's up?");
printBuilder(builder);
}
private static void printBuilder(StringBuilder dataBuild){
StringBuilder build = new StringBuilder(dataBuild);
System.out.println("data = " + build);
System.out.println("length = " + build.length());
System.out.println("capacity = " + build.capacity());
int addressBuild = System.identityHashCode(build);
System.out.println("address = " + Integer.toHexString(addressBuild);
}
Run Code Online (Sandbox Code Playgroud)
这是输出。
哈希函数非常有用且用途广泛。通常,它们用于将一个空间映射到一个更小的空间。当然,这意味着两个对象可能会散列到相同的值(碰撞),但这是因为您正在减少空间(鸽笼原理)。函数的效率很大程度上取决于哈希空间的大小。
令人惊讶的是,许多 Java hashCode 函数正在使用乘法来生成新对象的哈希码,如下所示(create-a-hashcode-method-java)
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果我们想在同一范围内混合两个哈希码,xor 应该比加法好得多,我认为传统上是这样使用的。如果我们想增加空间,移动一些字节然后异或仍然是有意义的。我想乘以 31 几乎与将一个哈希值移动 1 然后添加相同,但它的效率应该低得多......
虽然这是推荐的方法,但我想我错过了一些东西。所以我的问题是为什么会这样?
笔记: