আমার স্ট্রিংগুলিকে কিছুটা হ্যাশের রূপান্তর করতে হবে। এটি কি জাভাস্ক্রিপ্টে সম্ভব?
আমি একটি সার্ভার-সাইড ভাষা ব্যবহার করছি না তাই আমি সেভাবে এটি করতে পারি না।
আমার স্ট্রিংগুলিকে কিছুটা হ্যাশের রূপান্তর করতে হবে। এটি কি জাভাস্ক্রিপ্টে সম্ভব?
আমি একটি সার্ভার-সাইড ভাষা ব্যবহার করছি না তাই আমি সেভাবে এটি করতে পারি না।
উত্তর:
Object.defineProperty(String.prototype, 'hashCode', {
value: function() {
var hash = 0, i, chr;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
});
সূত্র: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
hash << 5 - hash
হিসাবে একই hash * 31 + char
কিন্তু অনেক দ্রুত। এটি দুর্দান্ত কারণ এটি এত তাড়াতাড়ি, এবং 31 এটি একটি ছোট প্রাইম prime সেখানে জয় জিতুন।
(hash * 31) + char
দ্বারা উত্পাদিত আউটপুটটি শিফট-ভিত্তিক কোড দ্বারা উত্পাদিত আউটপুটটির মতো ((hash<<5)-hash)+char
, এমনকি খুব দীর্ঘ স্ট্রিংয়ের জন্যও (আমি এটি লক্ষ লক্ষের বেশি অক্ষরের স্ট্রিং দিয়ে পরীক্ষা করেছি), সুতরাং এটি "ব্যবহারযোগ্য" নয় নির্ভুলতার। সংখ্যাটি ভিত্তিক এবং শিফ্ট-ভিত্তিক সংস্করণ উভয়ের জন্য জটিলতাটি হ'ল (এন), সুতরাং জটিলতার ক্ষেত্রে এটি "ব্যবহারযোগ্য" নয়।
n
তবে সবচেয়ে বড়টি n
কোনটি যার জন্য আমি সংঘর্ষের সম্ভাবনা নাও পেতে পারি?
var hashCode = function hashCode (str) {etc...}
? এবং তারপর হিসাবে ব্যবহার করবেন hashCode("mystring")
?
সম্পাদনা
আমার jsperf পরীক্ষার উপর ভিত্তি করে, গৃহীত উত্তরটি আসলে দ্রুততর: http://jsperf.com/hashcodelordvlad
মূল
যদি কেউ আগ্রহী হন তবে এখানে একটি উন্নত (দ্রুত) সংস্করণ রয়েছে, যা পুরানো ব্রাউজারগুলিতে reduce
অ্যারে ফাংশনের অভাবে ব্যর্থ হবে ।
hashCode = function(s){
return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
এক-লাইন তীর ফাংশন সংস্করণ:
hashCode = s => s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)
নোট: এমনকি সেরা 32-বিট হ্যাশ সঙ্গে, দুর্ঘটনায় হবে কখনো কখনো ঘটে থাকে।
হ্যাশের সংঘর্ষের সম্ভাব্যতা গণনা করা যেতে পারে , হিসাবে এপ্রোক্সিমেটেড ( এখানে দেখুন )। এটি অন্তর্দৃষ্টির প্রস্তাবের চেয়ে বেশি হতে পারে:
32-বিট হ্যাশ এবং কে = 10,000 আইটেম ধরে নেওয়া, 1.2% এর সম্ভাব্যতার সাথে একটি সংঘর্ষ ঘটবে। 77,163 নমুনার জন্য সম্ভাবনা 50% হয়ে যায়! ( ক্যালকুলেটর )
আমি নীচে একটি workaround পরামর্শ।
এই প্রশ্নের উত্তরে
কোন হ্যাশিং অ্যালগরিদম স্বতন্ত্রতা এবং গতির জন্য সেরা? , আয়ান বাল্ড গভীরতা বিশ্লেষণে ভাল পোস্ট করেছেন । সংক্ষেপে (আমি এটি ব্যাখ্যা হিসাবে), তিনি এই সিদ্ধান্তে পৌঁছেছেন যে মুরমুর সেরা, তারপরে এফএনভি -1 এ।
জাভার স্ট্রিং.হ্যাশকোড () এলগরিদম যে ইসমিরালাল প্রস্তাব করেছিলেন তা ডিজেবি 2 এর একটি রূপ বলে মনে হচ্ছে।
বড় ইনপুট স্ট্রিং এখানে কিছু benchmarks: http://jsperf.com/32-bit-hash
যখন ছোট ইনপুট স্ট্রিং কুচি-কুচি করিয়া কাটা বস্তু হয়, কলকল এর পারফরম্যান্সের ঝরিয়া, DJ2B এবং FNV-1A আপেক্ষিক: http://jsperf.com/32- বিট-হ্যাশ / 3
তাই সাধারণভাবে আমি বচসা করার পরামর্শ দিই।
একটি জাভাস্ক্রিপ্ট বাস্তবায়ন জন্য এখানে দেখুন:
https://github.com/garycourt/murmurhash-js
যদি ইনপুট স্ট্রিংগুলি সংক্ষিপ্ত হয় এবং বিতরণ মানের তুলনায় কর্মক্ষমতা আরও গুরুত্বপূর্ণ হয় তবে ডিজেবি 2 ব্যবহার করুন (এসেমিরালার দ্বারা গৃহীত উত্তরের প্রস্তাব হিসাবে)।
যদি গতির চেয়ে গুণমান এবং ছোট কোডের আকারটি আরও গুরুত্বপূর্ণ হয় তবে আমি FNV-1a ( এই কোডের উপর ভিত্তি করে ) এর প্রয়োগটি ব্যবহার করি ।
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
function hashFnv32a(str, asString, seed) {
/*jshint bitwise:false */
var i, l,
hval = (seed === undefined) ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if( asString ){
// Convert to 8 digit hex string
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
}
সংঘর্ষের সম্ভাবনা উন্নতি করুন
এখানে বর্ণিত হিসাবে , আমরা এই কৌশলটি ব্যবহার করে হ্যাশ বিট আকার বাড়িয়ে দিতে পারি:
function hash64(str) {
var h1 = hash32(str); // returns 32 bit (as 8 byte hex string)
return h1 + hash32(h1 + str); // 64 bit (as 16 byte hex string)
}
যত্ন সহকারে এটি ব্যবহার করুন এবং খুব বেশি আশা করবেন না।
("0000000" + (hval >>> 0).toString(16)).substr(-8);
? ওটা কি একরকম নয় (hval >>> 0).toString(16)
?
hval
, (hval >>> 0).toString(16)
8 টিরও কম অক্ষর হতে পারে, তাই আপনি এটিকে জিরো দিয়ে প্যাড করুন। আমি কেবল বিভ্রান্ত হয়ে পড়েছিলাম কারণ (hval >>> 0).toString(16)
সর্বদা আমার জন্য ঠিক 8 টি চরিত্রের স্ট্রিং ছিল।
Math.imul
ফাংশনটি ব্যবহার করে প্রয়োগ করা হয় তখন FNV1a অত্যন্ত দ্রুত হতে পারে বলে মনে করা উচিত । এটি একাই শীর্ষস্থানীয় মানদণ্ড তৈরি করে এবং শেষ পর্যন্ত ডিজেবি 2 এর চেয়ে ভাল পছন্দ।
ES6- এ গৃহীত উত্তরের ভিত্তিতে । ছোট, রক্ষণাবেক্ষণযোগ্য এবং আধুনিক ব্রাউজারগুলিতে কাজ করে।
function hashCode(str) {
return str.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
// Test
console.log("hashCode(\"Hello!\"): ", hashCode('Hello!'));
সম্পাদনা (2019-11-04) :
এক-লাইন তীর ফাংশন সংস্করণ:
const hashCode = s => s.split('').reduce((a,b) => (((a << 5) - a) + b.charCodeAt(0))|0, 0)
// test
console.log(hashCode('Hello!'))
str += ""
হ্যাশিংয়ের আগে আমি ব্যতিক্রমগুলি এড়ানোর জন্য যুক্ত করেছিলাম str.split is not a function
যখন নন-স্ট্রিংগুলি প্যারামিটার হিসাবে পাস করা হয়েছিল
hash |= 0
32 বিট ইন্টিতে রূপান্তর করতে ব্যবহার করে। এই বাস্তবায়ন হয় না। এটি কি বাগ?
প্রায় অর্ধেক উত্তর জাভা এর বাস্তবায়ন
String.hashCode
যা উচ্চমানের বা সুপার দ্রুত নয়। এটি খুব বিশেষ কিছু নয়, এটি প্রতিটি চরিত্রের জন্য কেবল 31 দ্বারা গুণ করে। এটি এক লাইনে সহজ এবং দক্ষতার সাথে প্রয়োগ করা যেতে পারে এবং এর সাথে আরও দ্রুতMath.imul
:
hashCode=s=>{for(var i=0,h;i<s.length;i++)h=Math.imul(31,h)+s.charCodeAt(i)|0;return h}
উপায়টি অতিক্রম করার সাথে , এখানে আরও ভাল কিছু রয়েছে — সাইরব ৫৩, একটি সাধারণ তবে উচ্চ মানের 53-বিট হ্যাশ। এটি বেশ দ্রুত, খুব ভাল হ্যাশ বিতরণ সরবরাহ করে এবং কোনও 32-বিট হ্যাশের তুলনায় উল্লেখযোগ্যভাবে সংঘর্ষের হার রয়েছে ।
const cyrb53 = function(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ h1>>>16, 2246822507) ^ Math.imul(h2 ^ h2>>>13, 3266489909);
h2 = Math.imul(h2 ^ h2>>>16, 2246822507) ^ Math.imul(h1 ^ h1>>>13, 3266489909);
return 4294967296 * (2097151 & h2) + (h1>>>0);
};
সুপরিচিত মার্মুরহ্যাশ / এক্সএক্সএইচএস অ্যালগরিদমগুলির অনুরূপ, এটি গুণ এবং জর্শিফ্টের সংমিশ্রণ ব্যবহার করে হ্যাশ উত্পন্ন করতে করে, তবে নয়। ফলস্বরূপ এটি জাভাস্ক্রিপ্টের যে কোনওটির চেয়ে দ্রুত এবং কার্যকরভাবে কার্যকর করা সহজ simp
এটি হিমস্রোঞ্চ (অ-কঠোর) অর্জন করে, যার মূলত ইনপুটটির ছোট ছোট পরিবর্তনগুলির ফলে আউটপুটে বড় পরিবর্তন হয়, ফলে হ্যাশটি এলোমেলোভাবে প্রদর্শিত হয়:
0xc2ba782c97901 = cyrb53("a")
0xeda5bc254d2bf = cyrb53("b")
0xe64cc3b748385 = cyrb53("revenge")
0xd85148d13f93a = cyrb53("revenue")
আপনি একই ইনপুটটির বিকল্প স্ট্রিমের জন্য একটি বীজ সরবরাহ করতে পারেন:
0xee5e6598ccd5c = cyrb53("revenue", 1)
0x72e2831253862 = cyrb53("revenue", 2)
0x0de31708e6ab7 = cyrb53("revenue", 3)
প্রযুক্তিগতভাবে এটি একটি 64-বিট হ্যাশ (সমান্তরালভাবে দুটি বিচ্ছিন্ন 32-বিট হ্যাশ), তবে জাভাস্ক্রিপ্টটি 53-বিট পূর্ণসংখ্যার মধ্যে সীমাবদ্ধ। প্রয়োজনে সম্পূর্ণ -৪-বিট আউটপুট ব্যবহার করা যেতে পারে হেক্স স্ট্রিং বা অ্যারের জন্য রিটার্ন লাইনে পরিবর্তন করে করা ।
সচেতন থাকুন যে হেক্স স্ট্রিংগুলি তৈরি করা কর্মক্ষমতা-সংকটজনক পরিস্থিতিতে ব্যাচ প্রসেসিংয়ে মারাত্মকভাবে ধীর করতে পারে।
return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
// or
return [h2>>>0, h1>>>0];
এবং কেবল মজাদার জন্য, এখানে এফএনভি বা ডিজেবি 2 এর চেয়ে উচ্চ মানের সহ 89 টি চরগুলিতে একটি সর্বনিম্ন 32-বিট হ্যাশ রয়েছে :
TSH=s=>{for(var i=0,h=9;i<s.length;)h=Math.imul(h^s.charCodeAt(i++),9**9);return h^h>>>9}
ch
হয়?
'imul'
।
যদি এটি কাউকে সহায়তা করে তবে আমি শীর্ষ দুটি উত্তর একটি পুরানো ব্রাউজার-সহনশীল সংস্করণে সংযুক্ত করেছি, যা reduce
উপলব্ধ হলে দ্রুত সংস্করণ ব্যবহার করে এবং যদি তা না হয় তবে এসমিরালের সমাধানে ফিরে যায়।
/**
* @see http://stackoverflow.com/q/7616461/940217
* @return {number}
*/
String.prototype.hashCode = function(){
if (Array.prototype.reduce){
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
}
var hash = 0;
if (this.length === 0) return hash;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
ব্যবহারের মতো:
var hash = "some string to be hashed".hashCode();
String.prototype.hashCode = function(){ var hash = 5381; if (this.length === 0) return hash; for (var i = 0; i < this.length; i++) { var character = this.charCodeAt(i); hash = ((hash<<5)+hash)^character; // Convert to 32bit integer } return hash; }
এটি একটি পরিশ্রুত এবং আরও ভাল পারফর্মিং বৈকল্পিক:
String.prototype.hashCode = function() {
var hash = 0, i = 0, len = this.length;
while ( i < len ) {
hash = ((hash << 5) - hash + this.charCodeAt(i++)) << 0;
}
return hash;
};
এটি জাভাটির মান বাস্তবায়নের সাথে মেলে object.hashCode()
এখানে কেবল ইতিবাচক হ্যাশকোডগুলিও রয়েছে:
String.prototype.hashcode = function() {
return (this.hashCode() + 2147483647) + 1;
};
এবং এখানে জাভা এর সাথে একটি মিল রয়েছে যা কেবল ইতিবাচক হ্যাশকোডগুলি দেয়:
public static long hashcode(Object obj) {
return ((long) obj.hashCode()) + Integer.MAX_VALUE + 1l;
}
উপভোগ করুন!
আমি কিছুটা অবাক হয়েছি কেউই নতুন সাবলেটক্রিপ্টো এপিআই সম্পর্কে এখনও কথা বলেনি ।
স্ট্রিং থেকে একটি হ্যাশ পেতে, আপনি এই subtle.digest
পদ্ধতিটি ব্যবহার করতে পারেন :
function getHash(str, algo = "SHA-256") {
let strBuf = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest(algo, strBuf)
.then(hash => {
window.hash = hash;
// here hash is an arrayBuffer,
// so we'll connvert it to its hex version
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += ('00000000' + view.getUint32(i).toString(16)).slice(-8);
}
return result;
});
}
getHash('hello world')
.then(hash => {
console.log(hash);
});
var promise = crypto.subtle.digest({name: "SHA-256"}, Uint8Array.from(data)); promise.then(function(result){ console.log(Array.prototype.map.call(new Uint8Array(result), x => x.toString(16).padStart(2, '0')).join('')); });
crypto
হুবহু পারফরম্যান্ট নয়।
মার্চ 10 দ্বারা উদাহরণের জন্য ধন্যবাদ, আমি এফএনভি -1 ক এর জন্য সি # এবং জাভাস্ক্রিপ্টে একই ফলাফল পাওয়ার একটি উপায় পেয়েছি। যদি ইউনিকোড অক্ষর উপস্থিত থাকে তবে পারফরম্যান্সের জন্য উপরের অংশটি ফেলে দেওয়া হয়। হ্যাশ করার সময় কেন এটি রক্ষণাবেক্ষণ করা সহায়ক হবে তা জানেন না, কারণ এখনকার জন্য কেবল ইউআরএল পাথগুলিই হ্যাশ করছি।
সি # সংস্করণ
private static readonly UInt32 FNV_OFFSET_32 = 0x811c9dc5; // 2166136261
private static readonly UInt32 FNV_PRIME_32 = 0x1000193; // 16777619
// Unsigned 32bit integer FNV-1a
public static UInt32 HashFnv32u(this string s)
{
// byte[] arr = Encoding.UTF8.GetBytes(s); // 8 bit expanded unicode array
char[] arr = s.ToCharArray(); // 16 bit unicode is native .net
UInt32 hash = FNV_OFFSET_32;
for (var i = 0; i < s.Length; i++)
{
// Strips unicode bits, only the lower 8 bits of the values are used
hash = hash ^ unchecked((byte)(arr[i] & 0xFF));
hash = hash * FNV_PRIME_32;
}
return hash;
}
// Signed hash for storing in SQL Server
public static Int32 HashFnv32s(this string s)
{
return unchecked((int)s.HashFnv32u());
}
জাভাস্ক্রিপ্ট সংস্করণ
var utils = utils || {};
utils.FNV_OFFSET_32 = 0x811c9dc5;
utils.hashFnv32a = function (input) {
var hval = utils.FNV_OFFSET_32;
// Strips unicode bits, only the lower 8 bits of the values are used
for (var i = 0; i < input.length; i++) {
hval = hval ^ (input.charCodeAt(i) & 0xFF);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
}
utils.toHex = function (val) {
return ("0000000" + (val >>> 0).toString(16)).substr(-8);
}
Math.imul
গুণনের পদক্ষেপের জন্য ব্যবহার করা যেতে পারে, যা কর্মক্ষমতা ব্যাপকভাবে উন্নত করে । কেবল ইস্যুটি হ'ল এটি শিম ছাড়া আইই 11 এ কাজ করবে না ।
একটি দ্রুত এবং সংক্ষিপ্ততর যা এখান থেকে রূপান্তরিত হয়েছিল :
String.prototype.hashCode = function() {
var hash = 5381, i = this.length
while(i)
hash = (hash * 33) ^ this.charCodeAt(--i)
return hash >>> 0;
}
ব্যবহারকারীর নাম এবং বর্তমান সময়ের উপর ভিত্তি করে একটি অনন্য-আইশ আইডি উত্পন্ন করতে আমার অনুরূপ ফাংশন (তবে ভিন্ন) প্রয়োজন। তাই:
window.newId = ->
# create a number based on the username
unless window.userNumber?
window.userNumber = 0
for c,i in window.MyNamespace.userName
char = window.MyNamespace.userName.charCodeAt(i)
window.MyNamespace.userNumber+=char
((window.MyNamespace.userNumber + Math.floor(Math.random() * 1e15) + new Date().getMilliseconds()).toString(36)).toUpperCase()
উত্পাদন:
2DVFXJGEKL
6IZPAKFQFL
ORGOENVMG
... etc
জুন 2015 সম্পাদনা করুন: নতুন কোডের জন্য আমি শর্টিড ব্যবহার করি: https://www.npmjs.com/package/shortid
আমি একটি সার্ভার-সাইড ভাষা ব্যবহার করছি না তাই আমি সেভাবে এটি করতে পারি না।
আপনি কি নিশ্চিত যে আপনি সেভাবে এটি করতে পারবেন না ?
আপনি কি ভুলে গেছেন যে আপনি জাভাস্ক্রিপ্ট ব্যবহার করছেন, ভাষাটি চির-বিবর্তিত?
ব্যবহার করে দেখুন SubtleCrypto
। এটি SHA-1, SHA-128, SHA-256 এবং SHA-512 হ্যাশ ফাংশন সমর্থন করে।
async function hash(message/*: string */) {
const text_encoder = new TextEncoder;
const data = text_encoder.encode(message);
const message_digest = await window.crypto.subtle.digest("SHA-512", data);
return message_digest;
} // -> ArrayBuffer
function in_hex(data/*: ArrayBuffer */) {
const octets = new Uint8Array(data);
const hex = [].map.call(octets, octet => octet.toString(16).padStart(2, "0")).join("");
return hex;
} // -> string
(async function demo() {
console.log(in_hex(await hash("Thanks for the magic.")));
})();
আমি পার্টিতে দেরি করছি, তবে আপনি এই মডিউলটি ব্যবহার করতে পারেন: ক্রিপ্টো :
const crypto = require('crypto');
const SALT = '$ome$alt';
function generateHash(pass) {
return crypto.createHmac('sha256', SALT)
.update(pass)
.digest('hex');
}
এই ফাংশনের ফলাফল সর্বদা 64
অক্ষরের স্ট্রিং; এটার মতো কিছু:"aa54e7563b1964037849528e7ba068eb7767b1fab74a8d80fe300828b996714a"
আমি দুটি সমাধান (ব্যবহারকারী এসমিরালহা এবং লর্ডভ্ল্যাড) একত্রিত করে একটি ফাংশন পেতে যা ব্রাউজারগুলির জন্য দ্রুত হওয়া উচিত যা জেএস ফাংশনকে হ্রাস করে () এবং এখনও পুরানো ব্রাউজারগুলির সাথে সামঞ্জস্যপূর্ণ:
String.prototype.hashCode = function() {
if (Array.prototype.reduce) {
return this.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
} else {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
};
উদাহরণ:
my_string = 'xyz';
my_string.hashCode();
আপনি যদি সংঘর্ষ এড়াতে চান তবে আপনি SHA-256 এর মতো সুরক্ষিত হ্যাশ ব্যবহার করতে পারেন । বেশ কয়েকটি জাভাস্ক্রিপ্ট SHA-256 বাস্তবায়ন রয়েছে।
আমি বেশ কয়েকটি হ্যাশ বাস্তবায়নের তুলনা করার জন্য পরীক্ষাগুলি লিখেছিলাম, https://github.com/brillout/test-javascript-hash-implementations দেখুন ।
বা পরীক্ষা চালানোর জন্য http://brillout.github.io/test-javascript-hash-implementations/ এ যান ।
এটি অন্য কয়েকটি উত্তরের চেয়ে কিছুটা বেশি সুরক্ষিত হ্যাশ হওয়া উচিত তবে কোনও ফাংশনে কোনও প্রিলোডেড উত্স ছাড়াই
আমি sha1 এর মূলত একটি সংক্ষিপ্ত সরল সংস্করণ তৈরি করেছি।
আপনি স্ট্রিংয়ের বাইটগুলি নিয়ে যান এবং তাদের 4 থেকে 32 বিট "শব্দের দ্বারা বিভাজনিত করুন"
তারপরে আমরা প্রতি 8 টি শব্দের 40 শব্দ পর্যন্ত প্রসারিত করি (ফলাফলের উপর আরও বড় প্রভাবের জন্য)।
এটি হ্যাশিং ফাংশনে যায় (শেষ হ্রাস) যেখানে আমরা বর্তমান অবস্থা এবং ইনপুট দিয়ে কিছু গণিত করি। আমরা সবসময় 4 শব্দ বের করি।
এটি মানচিত্র ব্যবহার করে প্রায় এক-কমান্ড / এক-লাইন সংস্করণ, লুপগুলির পরিবর্তে হ্রাস করুন ... তবে এটি এখনও খুব দ্রুত
String.prototype.hash = function(){
var rot = (word, shift) => word << shift | word >>> (32 - shift);
return unescape(encodeURIComponent(this.valueOf())).split("").map(char =>
char.charCodeAt(0)
).reduce((done, byte, idx, arr) =>
idx % 4 == 0 ? [...done, arr.slice(idx, idx + 4)] : done
, []).reduce((done, group) =>
[...done, group[0] << 24 | group[1] << 16 | group[2] << 8 | group[3]]
, []).reduce((done, word, idx, arr) =>
idx % 8 == 0 ? [...done, arr.slice(idx, idx + 8)] : done
, []).map(group => {
while(group.length < 40)
group.push(rot(group[group.length - 2] ^ group[group.length - 5] ^ group[group.length - 8], 3));
return group;
}).flat().reduce((state, word, idx, arr) => {
var temp = ((state[0] + rot(state[1], 5) + word + idx + state[3]) & 0xffffffff) ^ state[idx % 2 == 0 ? 4 : 5](state[0], state[1], state[2]);
state[0] = rot(state[1] ^ state[2], 11);
state[1] = ~state[2] ^ rot(~state[3], 19);
state[2] = rot(~state[3], 11);
state[3] = temp;
return state;
}, [0xbd173622, 0x96d8975c, 0x3a6d1a23, 0xe5843775,
(w1, w2, w3) => (w1 & rot(w2, 5)) | (~rot(w1, 11) & w3),
(w1, w2, w3) => w1 ^ rot(w2, 5) ^ rot(w3, 11)]
).slice(0, 4).map(p =>
p >>> 0
).map(word =>
("0000000" + word.toString(16)).slice(-8)
).join("");
};
আমরা ওয়ার্ড অ্যারের পরিবর্তে স্ট্রিং পেতে আউটপুটটিকে হেক্সে রূপান্তর করি।
ব্যবহার সহজ। উদাহরণের জন্য "a string".hash()
ফিরে আসবে"88a09e8f9cc6f8c71c4497fbb36f84cd"
আমি চার্জ কোডগুলিকে হেক্স স্ট্রিংয়ে রূপান্তরিত করে একটি সাধারণ কনটেন্টেশনে গিয়েছিলাম। এটি একটি অপেক্ষাকৃত সংকীর্ণ উদ্দেশ্যে পরিবেশন করে, যেমন একটি সার্ভারের সাথে বিনিময় করার জন্য কেবল একটি শর্ট স্ট্রিংয়ের (যেমন শিরোনাম, ট্যাগ) একটি হ্যাশ প্রতিনিধিত্ব প্রয়োজন যা প্রাসঙ্গিক কারণে স্বীকৃত হ্যাশকোড জাভা বন্দর সহজেই প্রয়োগ করতে পারে না। স্পষ্টতই এখানে কোনও সুরক্ষা আবেদন নেই।
String.prototype.hash = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.map.call(range, function(i) {
return self.charCodeAt(i).toString(16);
}).join('');
}
এটিকে আরও কড়া এবং ব্রাউজার-সহিষ্ণু করা যায় ইনডকোরের সাথে with উদাহরণ:
"Lorem Ipsum".hash()
"4c6f72656d20497073756d"
আমি মনে করি আপনি যদি অনুরূপ ফ্যাশনে বৃহত্তর স্ট্রিং হ্যাশ করতে চান তবে আপনি কেবল চরিত্রগুলি হ্রাস করতে এবং পৃথক চরিত্রগুলিকে এক সাথে যুক্ত করার পরিবর্তে ফলাফলের যোগফলকে হেক্সিফাই করতে পারেন:
String.prototype.hashLarge = function() {
var self = this, range = Array(this.length);
for(var i = 0; i < this.length; i++) {
range[i] = i;
}
return Array.prototype.reduce.call(range, function(sum, i) {
return sum + self.charCodeAt(i);
}, 0).toString(16);
}
'One time, I hired a monkey to take notes for me in class. I would just sit back with my mind completely blank while the monkey scribbled on little pieces of paper. At the end of the week, the teacher said, "Class, I want you to write a paper using your notes." So I wrote a paper that said, "Hello! My name is Bingo! I like to climb on things! Can I have a banana? Eek, eek!" I got an F. When I told my mom about it, she said, "I told you, never trust a monkey!"'.hashLarge()
"9ce7"
প্রাকৃতিকভাবে এই পদ্ধতির সাথে সংঘর্ষের ঝুঁকি, যদিও আপনি হ্রাসগুলিতে পাটিগণিতের সাথে ঝাঁকুনি খেতে পারেন তবে আপনি হ্যাশকে বৈচিত্র্যময় এবং দীর্ঘ করতে চেয়েছিলেন।
এটি যুক্ত করা হচ্ছে কারণ এখনও কেউ করেনি, এবং এটি হ্যাশগুলির সাহায্যে চাওয়া এবং প্রচুর প্রয়োগ করা হয়েছে বলে মনে হয় তবে এটি সর্বদা খুব খারাপভাবে করা হয় ...
এটি একটি স্ট্রিং ইনপুট নেয় এবং সর্বাধিক সংখ্যক আপনি হ্যাশটি সমান করতে চান এবং স্ট্রিং ইনপুটটির ভিত্তিতে একটি অনন্য সংখ্যা তৈরি করে।
আপনি ইমেজগুলির একটি অ্যারেতে একটি অনন্য সূচক তৈরি করতে এটি ব্যবহার করতে পারেন (যদি আপনি কোনও ব্যবহারকারীর জন্য নির্দিষ্ট অবতারটি এড়াতে চান, তবে এলোমেলোভাবে বেছে নেওয়া হয়েছে, তবে তাদের নামের উপর ভিত্তি করেও বেছে নেওয়া হয়েছে, তাই এটি সর্বদা সেই নামটির সাথে কারও কাছে নিযুক্ত করা হবে) )।
কারও নামের উপর ভিত্তি করে অনন্য অবতার পটভূমির রঙ উত্পন্ন করার জন্য আপনি এটি অবশ্যই রঙের অ্যারেতে কোনও সূচককে ফেরত দিতে ব্যবহার করতে পারেন।
function hashInt (str, max = 1000) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash = hash & hash;
}
return Math.round(max * Math.abs(hash) / 2147483648);
}
অবজেক্ট-হ্যাশ লাইব্রেরি ইত্যাদির মতো ব্যবহারযোগ্য প্রস্তুত সমাধানের পরিবর্তে এই অতি-জটিল জটিল ক্রিপ্টো কোড ব্যবহার করার কোনও কারণ আমি দেখতে পাচ্ছি না, যেমন বিক্রেতার উপর নির্ভর করা আরও উত্পাদনশীল, সময় সাশ্রয় করে এবং রক্ষণাবেক্ষণ ব্যয় হ্রাস করে।
কেবল https://github.com/puleos/object-hash ব্যবহার করুন
var hash = require('object-hash');
hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'
var crypto = require('crypto');
। আমি মনে করি এটি কোনও বিল্ড চলাকালীন সংশোধিত সংস্করণে বিক্রেতা থেকে এই নির্ভরতা কোডটি যুক্ত করে।