Uploaded by Abdallah Mohamed

Hashe function

advertisement
Hashe functions
Dr/Ibrahim Elawdy
‫‪Name‬‬
‫‪Dep‬‬
‫‪Section‬‬
‫عبدهللا محمد محفوظ‬
‫‪IS‬‬
‫‪4‬‬
‫عمرو كسبان عبدالحافظ‬
‫‪IS‬‬
‫‪4‬‬
‫بسام سراج مصطفى‬
‫‪IS‬‬
‫‪3‬‬
‫دنيا جمعه عباده‬
‫‪IS‬‬
‫‪3‬‬
‫سلوى اشرف عبدالتواب‬
‫‪IS‬‬
‫‪3‬‬
‫سندس عبدالجيد علي‬
‫‪IS‬‬
‫‪3‬‬
‫‪Team‬‬
‫‪members‬‬
Introduction
(Hashing)
Hashing is a technique or process of mapping keys, values into the hash table by using a
hash function. It is done for faster access to elements. The efficiency of mapping
depends on the efficiency of the hash function used.
Hash tables are the most convenient data structures that are easily accessible in most
programming languages. It uses an associative array to store data and retrieve data.
Each data value has its unique index. Instead of searching through the whole array, the
index is used to access the required element directly.
It reduces the time taken for search operation irrespective of the data size. Given a keyvalue pair, the hash code of the key is computed and used as the index of the value
stored in the table.
Introduction (CRC)
Cyclic Redundancy Check (CRC) is
an error detection technique to
detect changes to raw data and is
used widely in today’s computer
networks.CRC codes are also
known as polynomial codes, since
it is possible to view the bit string
to be sent as a polynomial.
Steps and example of (CRC)
Send Procedure:
1.
Extend the n data bits with k zeros
2.
Divide by the generator value C
3.
Keep remainder, ignore quotient
4.
Adjust k check bits by remainder
Receive Procedure:
1.
Divide and check for zero
remainder
Example :
Data bits:
1101011111
Check bits:
C(x)=x4+x1+1
C = 10011
k=4
Implementation for generating code word from given
binary data and key.
#include<bits/stdc++.h>
using namespace std;
// Returns XOR of 'a' and 'b'
// (both of same length)
string xor1(string a, string b)
{// Initialize result
string result = "";
int n = b.length();
// Traverse all bits, if bits are
// same, then XOR is 0, else 1
for(int i = 1; i < n; i++)
{
if (a[i] == b[i])
result += "0";
else
result += "1";
}
return result;
}
// Performs Modulo-2 division
string mod2div(string divident, string divisor)
{ // Number of bits to be XORed at a time.
int pick = divisor.length();
// Slicing the divident to appropriate
// length for particular step
string tmp = divident.substr(0, pick);
int n = divident.length();
while (pick < n)
{
if (tmp[0] == '1')
// Replace the divident by the result
// of XOR and pull 1 bit down
tmp = xor1(divisor, tmp) + divident[pick];
else
// If leftmost bit is '0'.
// If the leftmost bit of the dividend (or the
// part used in each step) is 0, the step
cannot
// use the regular divisor; we need to use
an
// all-0s divisor.
tmp = xor1(std::string(pick, '0'), tmp) +
divident[pick];
// Increment pick to move further
pick += 1;
}
// For the last n bits, we have to carry it out
// normally as increased value of pick will
cause
// Index Out of Bounds.
if (tmp[0] == '1')
tmp = xor1(divisor, tmp);
else
tmp = xor1(std::string(pick, '0'), tmp);
return tmp;
}
// Function used at the sender side to encode
// data by appending remainder of modular division
// at the end of data.
void encodeData(string data, string key)
{
int l_key = key.length();
// Appends n-1 zeroes at end of data
string appended_data = (data +
std::string(
l_key - 1, '0'));
string remainder = mod2div(appended_data, key);
// Append remainder in the original data
string codeword = data + remainder;
cout << "Remainder : "
<< remainder << "\n";
cout << "Encoded Data (Data + Remainder) :"
<< codeword << "\n";
}
// Driver code
int main()
{string data = "100100";
string key = "1101";
encodeData(data, key);
return 0;
} // This code is contributed by MuskanKalra1
Output:
Remainder : 001
Encoded Data (Data + Remainder) : 100100001
Cyclic Redundancy Check 64 bit (CRC-64) Hash Checksum Generator
In the real world, usually CRC used when sending data. Lets say we want to send our message to
someone else, to make sure the data didn't go through unintended changes (small changes,
maybe because it goes through unreliable connection/wire), we can put CRC hash in the message.
Upon receiving the message, the recipient try to calculate the CRC of the message and compare it
to the CRC sent which included on the message. If the CRC hash is different, then there's a
possibility of data change on the message.
Blocks of data entering these systems get a short check value attached, based on the remainder of
a polynomial division of their contents. On retrieval, the calculation is repeated and, in the event
the check values do not match, corrective action can be taken against data corruption. CRCs can
be used for error correction .
CRCs are so called because the check (data verification) value is a redundancy (it expands the
message without adding information) and the algorithm is based on cyclic codes. CRCs are
popular because they are simple to implement in binary hardware, easy to analyze
mathematically, and particularly good at detecting common errors caused by noise in
transmission channels. Because the check value has a fixed length, the function that generates it
is occasionally used as a hash function.
Example on how to create a hash table, hashing process using CRC64-algorithm.
// Copyright 2009 The Go Authors. All rights
reserved.
// Use of this source code is governed by a BSDstyle
// license that can be found in the LICENSE file.
// Package crc64 implements the 64-bit cyclic
redundancy check, or CRC-64,
// checksum. See
https://en.wikipedia.org/wiki/Cyclic_redundancy_che
ck for
// information.
package crc64
import (
"errors"
"hash"
"sync"
)
// The size of a CRC-64 checksum in bytes.
const Size = 8
// Predefined polynomials.
const (
// The ISO polynomial, defined in ISO 3309 and used
in HDLC.
ISO = 0xD800000000000000
// The ECMA polynomial, defined in ECMA 182.
ECMA = 0xC96C5795D7870F42
)
// Table is a 256-word table representing
the polynomial for efficient processing.
type Table [256]uint64
var (
slicing8TablesBuildOnce sync.Once
slicing8TableISO *[8]Table
slicing8TableECMA *[8]Table
)
func buildSlicing8TablesOnce() {
slicing8TablesBuildOnce.Do(buildSlicing8Tab
les)
}
func buildSlicing8Tables() {
slicing8TableISO =
makeSlicingBy8Table(makeTable(ISO))
slicing8TableECMA =
makeSlicingBy8Table(makeTable(ECMA))
}
Example on how to create a hash table, hashing process using CRC64-algorithm.
// MakeTable returns a Table constructed from the
specified polynomial.
// The contents of this Table must not be
modified.
func MakeTable(poly uint64) *Table {
buildSlicing8TablesOnce()
switch poly {
case ISO:
return &slicing8TableISO[0]
case ECMA:
return &slicing8TableECMA[0]
default:
return makeTable(poly)
}
}
func makeTable(poly uint64) *Table {
t := new(Table)
for i := 0; i < 256; i++ {
crc := uint64(i)
for j := 0; j < 8; j++ {
if crc&1 == 1 {
crc = (crc >> 1) ^ poly
} else {
crc >>= 1
}
}
t[i] = crc
}
return t
}
func makeSlicingBy8Table(t *Table) *[8]Table {
var helperTable [8]Table
helperTable[0] = *t
for i := 0; i < 256; i++ {
crc := t[i]
for j := 1; j < 8; j++ {
crc = t[crc&0xff] ^ (crc >> 8)
helperTable[j][i] = crc
}
}
return &helperTable
}
// digest represents the partial evaluation of a
checksum.
type digest struct {
crc uint64
tab *Table
}
Example on how to create a hash table, hashing process using CRC64-algorithm.
// New creates a new hash.Hash64 computing the CRC64 checksum using the
// polynomial represented by the Table. Its Sum
method will lay the
// value out in big-endian byte order. The returned
Hash64 also
// implements encoding.BinaryMarshaler and
encoding.BinaryUnmarshaler to
// marshal and unmarshal the internal state of the
hash.
func New(tab *Table) hash.Hash64 { return
&digest{0, tab} }
func (d *digest) Size() int { return Size }
func (d *digest) BlockSize() int { return 1 }
func (d *digest) Reset() { d.crc = 0 }
const (
magic = "crc\x02"
marshaledSize = len(magic) + 8 + 8
)
func (d *digest) MarshalBinary() ([]byte, error)
{
b := make([]byte, 0, marshaledSize)
b = append(b, magic...)
b = appendUint64(b, tableSum(d.tab))
b = appendUint64(b, d.crc)
return b, nil
}
func (d *digest) UnmarshalBinary(b []byte) error {
if len(b) < len(magic) || string(b[:len(magic)]) !=
magic {
return errors.New("hash/crc64: invalid hash state
identifier")
}
if len(b) != marshaledSize {
return errors.New("hash/crc64: invalid hash state
size")
}
if tableSum(d.tab) != readUint64(b[4:]) {
return errors.New("hash/crc64: tables do not match")
}
d.crc = readUint64(b[12:])
return nil
}
func appendUint64(b []byte, x uint64) []byte {
a := [8]byte{
byte(x >> 56),
byte(x >> 48),
byte(x >> 40),
byte(x >> 32),
byte(x >> 24),
byte(x >> 16),
byte(x >> 8),
byte(x),
}
return append(b, a[:]...)
}
Example on how to create a hash table, hashing process using CRC64-algorithm.
func readUint64(b []byte) uint64 {
_ = b[7]
return uint64(b[7]) | uint64(b[6])<<8 |
uint64(b[5])<<16 | uint64(b[4])<<24 |
uint64(b[3])<<32 | uint64(b[2])<<40 |
uint64(b[1])<<48 | uint64(b[0])<<56
}
func update(crc uint64, tab *Table, p []byte)
uint64 {
buildSlicing8TablesOnce()
crc = ^crc
// Table comparison is somewhat expensive, so
avoid it for small sizes
for len(p) >= 64 {
var helperTable *[8]Table
if *tab == slicing8TableECMA[0] {
helperTable = slicing8TableECMA
} else if *tab == slicing8TableISO[0] {
helperTable = slicing8TableISO
// For smaller sizes creating extended table
takes too much time
} else if len(p) > 16384 {
helperTable = makeSlicingBy8Table(tab)
} else {
break
}
// Update using slicing-by-8
for len(p) > 8 {
crc ^= uint64(p[0]) | uint64(p[1])<<8 |
uint64(p[2])<<16 | uint64(p[3])<<24 |
uint64(p[4])<<32 | uint64(p[5])<<40 |
uint64(p[6])<<48 | uint64(p[7])<<56
crc = helperTable[7][crc&0xff] ^
helperTable[6][(crc>>8)&0xff] ^
helperTable[5][(crc>>16)&0xff] ^
helperTable[4][(crc>>24)&0xff] ^
helperTable[3][(crc>>32)&0xff] ^
helperTable[2][(crc>>40)&0xff] ^
helperTable[1][(crc>>48)&0xff] ^
helperTable[0][crc>>56]
p = p[8:]
}
}
// For reminders or small sizes
for _, v := range p {
crc = tab[byte(crc)^v] ^ (crc >> 8)
}
return ^crc
}
Example on how to create a hash table, hashing process using CRC64-algorithm.
// Update returns the result of adding the
bytes in p to the crc.
func Update(crc uint64, tab *Table, p []byte)
uint64 {
return update(crc, tab, p)
}
func (d *digest) Write(p []byte) (n int, err
error) {
d.crc = update(d.crc, d.tab, p)
return len(p), nil
}
func (d *digest) Sum64() uint64 { return
d.crc }
func (d *digest) Sum(in []byte) []byte {
s := d.Sum64()
return append(in, byte(s>>56), byte(s>>48),
byte(s>>40), byte(s>>32), byte(s>>24),
byte(s>>16), byte(s>>8), byte(s))
}
// Checksum returns the CRC-64 checksum of data
// using the polynomial represented by the Table.
func Checksum(data []byte, tab *Table) uint64 { return
update(0, tab, data) }
// tableSum returns the ISO checksum of table t.
func tableSum(t *Table) uint64 {
var a [2048]byte
b := a[:0]
if t != nil {
for _, x := range t {
b = appendUint64(b, x)
}
}
return Checksum(b, MakeTable(ISO))
}
Thanks
Download