From WikiChip
$hash Identifier - mIRC
< mirc‎ | identifiers
Revision as of 17:08, 8 January 2018 by Maroonbells (talk | contribs) (Create content for empty page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The $hash identifier calculates a simple hash of the supplied text. Hash is shown as a decimal number in the range from 1 to 2^32-1. You should probably avoid using this hash for reasons explained in the Notes section.

Synopsis

$hash(<text>,<N>)

Switches

None

Parameters

text text string or %variable to be hashed
N Bit length for the returned hash. $hash returns $null if N is not in the range 2-32

Properties

None

Example

//echo -a The hash is $hash(test,32)
returns: The hash is 1702094848

Notes

The 'fakehash' alias below is based on the code posted here: https://forums.mirc.com/ubbthreads.php/topics/98371/Re:_$hash_function#Post98371

$hash uses a hash function that is very weak for several reasons. The weaknesses are more easily seen by showing an alias which mimics $hash output, and showing $hash output in hex. Some weaknesses include:

  • 1. Similar text have similar hash. Strings of 1-3 bytes are most obvious:
//echo -a $base($hash(abc,32),10,16) is $+($base($asc(a),10,16,2),$base($asc(b),10,16,2),$base($asc(c),10,16,2),00)
returns: 61626300 is 61626300
  • 2. When N is greater than 24, the rightmost extra bits above 24 are always zero, making it effectively a 24-bit hash not a 32. Only 2^24 of the values within the range of 0 - 2^32-1 can possibly be hashes. i.e. a 27-bit hash always has the least-significant 3 bits as zero:
//var %i 99999 | while (%i) { var %n $rand(1,99999999) , %bits $rand(25,32) | if ( $right($base($hash(%n,%bits),10,2,%bits) , $calc(%bits -24) )) echo -a this message will never show | dec %i }
  • 3. One of the properties of good hash hash functions is that each changed bit of the input should change close to half the bits in a seemingly-random pattern. Changing 1 bit of the text has minimal change of the bits in the $hash output, often changing just 1 bit. It often takes several additional bytes before the bits set by the first byte are altered.
//echo -a $base($hash(mIRC,32),10,16) / $base($hash(mIRD,32),10,16)
returns: 4952B000 / 4952B100
  • 4. It's easy to create duplicate hashes, especially when the length of the text is a multiple of 3:
//echo -a $base($hash(ABCDEF,32),10,16) / $base($hash(ABDDEE,32),10,16)

Instead of using $hash, you would be better off using other substitutes. For example, if you need it to be a decimal number with a variable number of bits from 1-32, use $crc then convert to decimal then reduce the number of bits:

alias crchash {
  return $calc( $base($crc($1,0),16,10) % 2^$2 )
}

If the hash needs to be crypto-level secure, use 8 bits from $sha1 or $sha512 instead of from $crc.

When the fakehash alias is in a remotes script, you should get the same answers from $fakehash as from $hash:

//var %i 999 | while (%i) { var %text $rand(1,999999999) , %bits $rand(16,24) | if ($hash(%text,%bits) != $fakehash(%text,%bits)) echo -a this should never show: %text %bits | dec %i }
 
alias fakehash {
  if ( ($1 == $null) || ($2 !isnum 2-32) ) return $null
  var %i 1 | var %len $len(%string) | var %x 0 | var %bits $int($2)
  while (%i <= $len($1)) {
    var %y $int($calc( $and(%x,$base(ff000000,16,10)) / 2^24 ))
    var %x = $calc( %x + %y + $asc($mid($1,%i,1)) )
    var %x = $calc( (%x * 256) % (2^32) )
    inc %i
  }
  var %y = $base(%x,10,2,32)
  var %z = $base($left(%y,%bits),2,10)
  if ($mid(%y,$calc(1+%bits))) inc %z
  return $calc( %z % (2^%bits) )
}

Compatibility

Added: mIRC v5.4
Added on: 23 Jun 1998
Note: Unless otherwise stated, this was the date of original functionality.
Further enhancements may have been made in later versions.


See also

v · d · e mIRC identifier list

$ $$, $, $0, $1-, $!, $&, $*, $+, $++, $?

A $abook, $abs, $acos, $active, $activecid, $activewid, $adate, $address, $addtok, $addtokcs, $agent, $agentname, $agentstat, $agentver, $alias, $and, $anick, $ansi2mirc, $aop, $appactive, $appstate, $asc, $asctime, $asin, $atan, $atan2, $auto, $avoice, $away, $awaymsg, $awaytime

B $banlist, $banmask, $base, $beta, $bfind, $bindip, $bitoff, $biton, $bits, $bnick, $bvar, $bytes

C $calc, $caller, $cancel, $cb, $cd, $ceil, $chan, $chanmodes, $channel, $chantypes, $chat, $chr, $cid, $clevel, $click, $cmdbox, $cmdline, $cnick, $color, $colour, $com, $comcall, $comchan, $comchar, $comerr, $compact, $compress, $comval, $cos, $cosh, $count, $countcs, $cr, $crc, $creq, $crlf, $ctime, $ctimer, $ctrlenter

D $date, $day, $daylight, $dbuh, $dbuw, $dccignore, $dccport, $dde, $ddename, $debug, $decode, $decompress, $deltok, $devent, $dialog, $did, $didreg, $didtok, $didwm, $dir, $disk, $dlevel, $dll, $dllcall, $dname, $dns, $donotdisturb, $dqwindow, $duration

E $ebeeps, $editbox, $email, $emailaddr, $encode, $envvar, $error, $eval, $evalnext, $event, $eventid, $eventparms, $exists, $exiting

F $false, $feof, $ferr, $fgetc, $file, $filename, $filtered, $find, $finddir, $finddirn, $findfile, $findfilen, $findtok, $findtokcs, $fline, $flinen, $floor, $font, $fopen, $fread, $fromeditbox, $fserv, $fserve, $fulladdress, $fulldate, $fullname, $fullscreen

G $get, $getdir, $getdot, $gettok, $gmt, $group

H $halted, $hash, $height, $hfile, $hfind, $hget, $highlight, $hmac $hmatch, $hnick, $host, $hotline, $hotlinepos, $hotlink, $hotp, $hregex, $hypot

I $iaddress, $ial, $ialchan, $ibl, $idle, $iel, $ifmatch, $ifmatch2, $ignore, $iif, $iil, $inellipse, $ini, $initopic, $inmidi, $inmode, $inmp3, $inpaste, $inpoly, $input, $inrect, $inroundrect, $insong, $insongpause, $instok, $int, $intersect, $inwave, $inwho, $ip, $iptype, $iql, $isadmin, $isalias, $isbit, $isdde, $isdir, $isfile, $isid, $islower, $istok, $istokcs, $isupper, $isutf

K $keychar, $keyrpt, $keyval, $knick

L $lactive, $lactivecid, $lactivewid, $left, $leftwin, $leftwincid, $leftwinwid, $len, $level, $lf, $line, $lines, $link, $lock, $locked, $lof, $log, $log10, $logdir, $logstamp, $logstampfmt, $longfn, $longip, $lower, $ltimer

M $maddress, $mask, $matchkey, $matchtok, $matchtokcs, $maxlenl, $maxlenm, $maxlens, $md5, $me, $menu, $menubar, $menucontext, $menutype, $mid, $mididir, $mircdir, $mircexe, $mircini, $mkfn, $mklogfn, $mknickfn, $mnick, $mode, $modefirst, $modelast, $modespl, $mouse, $mousecx, $mousecy, $mousedx, $mousedy, $mousekey, $mouselb, $mousex, $mousey, $mousewin, $mp3, $mp3dir, $msfile, $msgstamp, $msgtags

N $N, $naddress, $network, $newnick, $nhnick, $nick, $nickmode, $no, $nofile, $nopath, $nopnick, $noqt, $not, $notags, $notify, $null, $numeric, $numtok, $nvnick

O $ok, $online, $onlineserver, $onlinetotal $onpoly, $opnick, $or, $ord, $os

P $parmN, $parms, $parseline, $parsetype, $parseutf, $passivedcc, $pi, $pic, $play, $pnick, $portable, $portfree, $pos, $poscs, $prefix, $prop, $protect, $puttok

Q $qt, $query

R $r, $raddress, $rand, $rands, $rawbytes, $rawmsg, $read, $readini, $readn, $regbr, $regerrstr, $regex, $regml, $regmlex, $regsub, $regsubex, $remote, $remove, $removecs, $remtok, $remtokcs, $replace, $replacecs, $replacex, $replacexcs, $reptok, $reptokcs, $result, $rgb, $right, $rnick, $round

S $samepath, $scid, $scon, $script, $scriptdir, $scriptline, $sdir, $send, $server, $serverip, $servertarget, $sfile, $sha1, $sha256, $sha384, $sha512, $shortfn, $show, $signal, $sin, $sinh, $site, $sline, $snick, $snicks, $snotify, $sock, $sockbr, $sockerr, $sockname, $sorttok, $sorttokcs, $sound, $speak, $sqrt, $sreq, $ssl, $sslcertsha1, $sslcertsha256, $sslcertvalid, $ssldll, $ssllibdll, $sslready, $sslversion, $starting, $status, $str, $strip, $stripped, $style, $submenu, $switchbar, $sysdir

T $tan, $tanh, $target, $tempfn, $ticks, $time, $timeout, $timer, $timestamp, $timestampfmt, $timezone, $tip, $tips, $titlebar, $token, $toolbar, $topic, $totp, $treebar, $true, $trust

U $ulevel, $ulist, $unsafe, $upper, $uptime, $url, $usermode, $utfdecode, $utfencode

V $v1, $v2, $var, $vc, $vcmd, $vcmdstat, $vcmdver, $version, $vnick, $vol

W $wavedir, $wid, $width, $wildsite, $wildtok, $wildtokcs, $window, $wrap

X $xor

Y $yes

Z $zip

= =$nick