0% found this document useful (0 votes)
26 views7 pages

Lab Journal - 13 27122023 103335am

The document is the lab journal for a data structures and algorithms course. It contains two tasks for implementing hashing concepts. Task 1 involves implementing a hash table in C++ with functions for insertion, retrieval, and removal of key-value pairs. Task 2 involves designing a program for user authentication that stores hashed passwords in a hash table to allow for user registration and login while handling collisions.

Uploaded by

bismaamjad56
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views7 pages

Lab Journal - 13 27122023 103335am

The document is the lab journal for a data structures and algorithms course. It contains two tasks for implementing hashing concepts. Task 1 involves implementing a hash table in C++ with functions for insertion, retrieval, and removal of key-value pairs. Task 2 involves designing a program for user authentication that stores hashed passwords in a hash table to allow for user registration and login while handling collisions.

Uploaded by

bismaamjad56
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Bahria University, Lahore Campus

Department of Computer Science


Lab Journal 13
(Fall 2023)

Course: Data Structures and Algorithm - Lab Date: _______________


Course Code: CSL-221 Max Marks: 10
Faculty’s Name: Fatima Zulfiqar

Name: BISMA AMJAD Enroll No:03-134222-022 Class: BCS 3A

Objective(s):
Upon completion of this lab session, learners will be able to:
 Implement the concept of hashing and has function.
 Implement a scenario based on hashing.

Lab Tasks:

Task 1
Implement a simple hash table in C++ to store key-value pairs. The hash table should support the
following operations:
 insert(key, value): Insert a key-value pair into the hash table. If the key already exists, update
the corresponding value.
 get(key): Retrieve the value associated with the given key. If the key is not present, return a
default value (e.g., -1).
 remove(key): Remove the key-value pair with the given key from the hash table.

Use the following guidelines:

 The hash function should convert the key into an index for the hash table.
 Resolve collisions using a suitable collision resolution technique (e.g., chaining or open
addressing).
 Ensure the hash table dynamically resizes itself to maintain an appropriate load factor.
 You can use standard C++ libraries for dynamic arrays or linked lists if needed.

Provide the implementation along with a brief explanation of your chosen hash function and collision
resolution strategy in comments. Additionally, include sample code demonstrating the usage of your
hash table with multiple insertions, retrievals, and removals.

#include <iostream>

using namespace std;

template <typename K, typename V>


class Node {
public:
K key;
V value;
Node* next;

Node(const K& k, const V& v) : key(k), value(v), next(nullptr) {}


%
Enrollment Number: ____________________________
};

template <typename K, typename V>


class HashTable {
private:
static const size_t initialSize = 16; // Initial size of the hash table
static const double loadFactorThreshold; // Load factor threshold for resizing

Node<K, V>** table;

// Hash function: Simple modulus operation


size_t hashFunction(const K& key) const {
return std::hash<K>{}(key) % tableSize;
}

// Find the key in the specified bucket and return the node
Node<K, V>* findInBucket(Node<K, V>* bucket, const K& key) const {
Node<K, V>* current = bucket;
while (current != nullptr && current->key != key) {
current = current->next;
}
return current;
}

// Resize the hash table when load factor exceeds the threshold
void resizeTable() {
if (static_cast<double>(size()) / tableSize > loadFactorThreshold) {
size_t newSize = tableSize * 2;
Node<K, V>** newTable = new Node<K, V>* [newSize]();

for (size_t i = 0; i < tableSize; ++i) {


Node<K, V>* current = table[i];
while (current != nullptr) {
size_t newIndex = hashFunction(current->key);
Node<K, V>* temp = current->next;

current->next = newTable[newIndex];
newTable[newIndex] = current;

current = temp;
}
}

delete[] table;
table = newTable;
tableSize = newSize;
}
}

public:
HashTable() : table(new Node<K, V>* [initialSize]()), tableSize(initialSize) {}

~HashTable() {
for (size_t i = 0; i < tableSize; ++i) {
Node<K, V>* current = table[i];
while (current != nullptr) {
Node<K, V>* temp = current;
current = current->next;
delete temp;
}
Page 2 of 7
%
Enrollment Number: ____________________________
}
delete[] table;
}

// Insert or update key-value pair


void insert(const K& key, const V& value) {
size_t index = hashFunction(key);
Node<K, V>*& bucket = table[index];
Node<K, V>* node = findInBucket(bucket, key);

if (node != nullptr) {
// Key exists, update the value
node->value = value;
}
else {
// Key not found, insert a new key-value pair
Node<K, V>* newNode = new Node<K, V>(key, value);
newNode->next = bucket;
bucket = newNode;
resizeTable();
}
}

// Retrieve value associated with the key


V get(const K& key) const {
size_t index = hashFunction(key);
const Node<K, V>* bucket = table[index];
const Node<K, V>* node = findInBucket(const_cast<Node<K, V>*>(bucket), key);

return (node != nullptr) ? node->value : V{}; // Default value if not found


}

// Remove key-value pair from the hash table


void remove(const K& key) {
size_t index = hashFunction(key);
Node<K, V>*& bucket = table[index];
Node<K, V>* current = bucket;
Node<K, V>* prev = nullptr;

while (current != nullptr && current->key != key) {


prev = current;
current = current->next;
}

if (current != nullptr) {
if (prev != nullptr) {
prev->next = current->next;
}
else {
bucket = current->next;
}
delete current;
}
}

// Get the current size of the hash table


size_t size() const {
size_t totalSize = 0;
for (size_t i = 0; i < tableSize; ++i) {
const Node<K, V>* current = table[i];
Page 3 of 7
%
Enrollment Number: ____________________________
while (current != nullptr) {
totalSize++;
current = current->next;
}
}
return totalSize;
}

private:
size_t tableSize;
};

template <typename K, typename V>


const double HashTable<K, V>::loadFactorThreshold = 0.75;

int main() {
HashTable<std::string, int> myHashTable;

// Insert key-value pairs


myHashTable.insert("One", 1);
myHashTable.insert("Two", 2);
myHashTable.insert("Three", 3);

// Retrieve values
cout << "Value for 'One': " << myHashTable.get("One") << endl;
cout << "Value for 'Four': " << myHashTable.get("Four") << endl;

// Remove a key
myHashTable.remove("Two");

// Retrieve values after removal


cout << "Value for 'Two' after removal: " << myHashTable.get("Two") << endl;

return 0;
}

Page 4 of 7
%
Enrollment Number: ____________________________

Task 2
You are working on a system that manages user authentication for a web application. To improve
performance and security, you decide to implement a hashed password storage mechanism. Each
user's password will be hashed and stored in a hash table.

Design and implement a C++ program that utilizes hashing to store and verify user passwords. The
program should include the following functionalities:

1. User Registration:
 Prompt the user to enter a username and password.
 Hash the password and store the hashed password in a hash table.
 Ensure that the program prevents duplicate usernames.

2. User Login:
 Prompt the user to enter their username and password.
 Retrieve the hashed password from the hash table based on the entered username.
 Verify the entered password by comparing its hash with the stored hash.
 Allow login if the verification is successful; otherwise, deny access.

3. Collision Handling:
Discuss how you would handle collisions in the hash table, especially in the context of storing
hashed passwords.

Include the complete C++ implementation of your program and provide a sample interaction
demonstrating the registration and login process. Additionally, explain how your implementation
addresses security concerns and collision handling.

#include <iostream>
#include <string>
#include <unordered_map>

class UserAuthentication {
private:
// Simple string hashing algorithm (for illustration purposes)
static size_t hashString(const std::string& str) {
size_t hash = 0;
for (char ch : str) {
hash = (hash * 31) + static_cast<size_t>(ch);
}
return hash;
}

std::unordered_map<std::size_t, std::string> userTable; // hashed username -> hashed password

public:
bool registerUser(const std::string& username, const std::string& password) {
// Check if the username already exists
size_t hashedUsername = hashString(username);
if (userTable.find(hashedUsername) != userTable.end()) {
std::cout << "Username already exists. Choose a different username.\n";
return false;
}

// Hash the password and store in the hash table


size_t hashedPassword = hashString(password);
userTable[hashedUsername] = std::to_string(hashedPassword);
std::cout << "User registered successfully.\n";
Page 5 of 7
%
Enrollment Number: ____________________________
return true;
}

bool loginUser(const std::string& username, const std::string& password) {


// Hash the entered username
size_t hashedUsername = hashString(username);

// Check if the hashed username exists


auto userEntry = userTable.find(hashedUsername);
if (userEntry == userTable.end()) {
std::cout << "User not found. Please register first.\n";
return false;
}

// Hash the entered password and compare with the stored hash
size_t hashedEnteredPassword = hashString(password);
size_t storedHashedPassword = std::stoull(userEntry->second);
if (hashedEnteredPassword == storedHashedPassword) {
std::cout << "Login successful.\n";
return true;
}
else {
std::cout << "Incorrect password. Login failed.\n";
return false;
}
}
};

int main() {
UserAuthentication userAuth;

// User Registration
userAuth.registerUser("user1", "password123");

// User Login
userAuth.loginUser("user1", "password123"); // Should succeed
userAuth.loginUser("user1", "wrongpassword"); // Should fail

// Attempt to register with duplicate username


userAuth.registerUser("user1", "newpassword"); // Should fail

return 0;
}

Page 6 of 7
%
Enrollment Number: ____________________________

Note : Attempt all tasks and get them checked by your Lab Instructor. Also for each task,
attach a screenshot of the output. You are free to use any other helping functions in your code.

Lab Grading Sheet :


Max Obtained
Task Comments(if any)
Marks Marks
1. 4
2. 6
Total 10 Signature

Page 7 of 7

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy