The wait is almost over. The final Digital Personal Data Protection (DPDP) Rules are just days away, marking the next big step after the enactment of the DPDPA in 2023. With only a few days left, organizations must gear up to align with new obligations on data protection, governance, and accountability.
Are you prepared to meet the requirements and avoid costly penalties? These rules will act as the operational backbone of the law, providing clarity on implementation, enforcement, and compliance.
With businesses, regulators, and citizens alike watching closely, the release of these rules will reshape India’s digital economy and data protection landscape. Here’s what to expect as the countdown begins.
While the DPDPA, 2023 laid down the broad principles of personal data protection—such as consent, purpose limitation, and user rights—the rules will answer the “how” questions:
How should organizations obtain and manage consent?
How will data principals exercise their rights?
What will compliance look like for startups vs. large enterprises?
How will penalties be calculated and enforced?
In short, the rules will turn principles into practice.
Key Areas to Watch in the Final Rules
Consent & Notice Requirements
Expect detailed procedures for how organisations must obtain consent, including the form, language, and accessibility of consent notices. The government may also clarify rules around “deemed consent”, which has raised debate among privacy experts.
Data Principal Rights
The rules will operationalise rights like data access, correction, erasure, and grievance redressal. Clear timelines for fulfilling these requests will likely be specified, adding compliance pressure on businesses.
Obligations for Data Fiduciaries
Significant data fiduciaries (LDFs) will have enhanced responsibilities—such as mandatory Data Protection Officers (DPOs), regular audits, and risk assessments. The criteria for what qualifies as an LDF will be closely watched.
Cross-Border Data Transfer
The government may publish its “whitelist” of countries where Indian personal data can be transferred. This will be crucial for IT/ITES, cloud, and fintech industries that rely heavily on global operations.
Children’s Data Protection
Rules around parental consent, restrictions on profiling, and targeted advertising for children may tighten, impacting edtech, gaming, and social platforms.
Enforcement & Penalties
The rules are expected to detail the functioning of the Data Protection Board of India (DPBI), including hearings, fines, and appeals procedures. This will define how strictly the law is enforced.
Transition & Implementation Timelines
Perhaps most critical will be the phased rollout plan. Businesses anxiously await to know how much time they will get to comply, and whether specific provisions will be delayed for startups and SMEs.
What Businesses Should Do Now
Even before the DPDP rules are published, organizations should start preparing:
Map personal data flows across systems and vendors.
Review consent management practices and plan for user-friendly updates.
Establish governance frameworks—DPO roles, audit readiness, and escalation processes.
Evaluate cross-border dependencies to anticipate transfer restrictions.
Train employees in privacy responsibilities and incident handling.
Early movers will reduce compliance risks and gain customer trust in an era when data is a competitive differentiator.
The Bigger Picture
The DPDP Rules will set the tone for India’s privacy-first digital future. For businesses, this is more than just a compliance exercise—it’s a chance to demonstrate accountability, build trust, and strengthen their brand in a data-conscious marketplace.
As the countdown begins, one thing is clear: organisations that prepare proactively will be better positioned to adapt, comply, and thrive in the new regulatory environment.
Stay ahead of DPDP compliance with Seqrite. Prepare your organization now with Seqrite’s end-to-end data privacy and compliance solutions.
With HashSet, you can get a list of different items in a performant way. What if you need a custom way to define when two objects are equal?
Table of Contents
Just a second! 🫷 If you are here, it means that you are a software developer.
So, you know that storage, networking, and domain management have a cost .
If you want to support this blog, please ensure that you have disabled the adblocker for this site. I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.
Thank you for your understanding. – Davide
Sometimes, object instances can be considered equal even though some of their properties are different. Consider a movie translated into different languages: the Italian and French versions are different, but the movie is the same.
If we want to store unique values in a collection, we can use a HashSet<T>. But how can we store items in a HashSet when we must follow a custom rule to define if two objects are equal?
In this article, we will learn two ways to add custom equality checks when using a HashSet.
Let’s start with a dummy class: Pirate.
publicclassPirate{
publicint Id { get; }
publicstring Name { get; }
public Pirate(int id, string username)
{
Id = id;
Name = username;
}
}
I’m going to add some instances of Pirate to a HashSet. Please, note that there are two pirates whose Id is 4:
List<Pirate> mugiwara = new List<Pirate>()
{
new Pirate(1, "Luffy"),
new Pirate(2, "Zoro"),
new Pirate(3, "Nami"),
new Pirate(4, "Sanji"), // This ...new Pirate(5, "Chopper"),
new Pirate(6, "Robin"),
new Pirate(4, "Duval"), // ... and this};
HashSet<Pirate> hashSet = new HashSet<Pirate>();
foreach (var pirate in mugiwara)
{
hashSet.Add(pirate);
}
_output.WriteAsTable(hashSet);
(I really hope you’ll get the reference 😂)
Now, what will we print on the console? (ps: output is just a wrapper around some functionalities provided by Spectre.Console, that I used here to print a table)
As you can see, we have both Sanji and Duval: even though their Ids are the same, those are two distinct objects.
Also, we haven’t told HashSet that the Id property must be used as a discriminator.
Define a custom IEqualityComparer in a C# HashSet
In order to add a custom way to tell the HashSet that two objects can be treated as equal, we can define a custom equality comparer: it’s nothing but a class that implements the IEqualityComparer<T> interface, where T is the name of the class we are working on.
The first method, Equals, compares two instances of a class to tell if they are equal, following the custom rules we write.
The second method, GetHashCode, defines a way to build an object’s hash code given its internal status. In this case, I’m saying that the hash code of a Pirate object is just the hash code of its Id property.
To include this custom comparer, you must add a new instance of PirateComparer to the HashSet declaration:
HashSet<Pirate> hashSet = new HashSet<Pirate>(new PirateComparer());
Let’s rerun the example, and admire the result:
As you can see, there is only one item whose Id is 4: Sanji.
Let’s focus a bit on the messages printed when executing Equals and GetHashCode.
GetHashCode Luffy
GetHashCode Zoro
GetHashCode Nami
GetHashCode Sanji
GetHashCode Chopper
GetHashCode Robin
GetHashCode Duval
Equals: Sanji vs Duval
Every time we insert an item, we call the GetHashCode method to generate an internal ID used by the HashSet to check if that item already exists.
Two objects that are equal return hash codes that are equal. However, the reverse is not true: equal hash codes do not imply object equality, because different (unequal) objects can have identical hash codes.
This means that if the Hash Code is already used, it’s not guaranteed that the objects are equal. That’s why we need to implement the Equals method (hint: do not just compare the HashCode of the two objects!).
Is implementing a custom IEqualityComparer the best choice?
As always, it depends.
On the one hand, using a custom IEqualityComparer has the advantage of allowing you to have different HashSets work differently depending on the EqualityComparer passed in input; on the other hand, you are now forced to pass an instance of IEqualityComparer everywhere you use a HashSet — and if you forget one, you’ll have a system with inconsistent behavior.
There must be a way to ensure consistency throughout the whole codebase.
Implement the IEquatable interface
It makes sense to implement the equality checks directly inside the type passed as a generic type to the HashSet.
To do that, you need to have that class implement the IEquatable<T> interface, where T is the class itself.
Let’s rework the Pirate class, letting it implement the IEquatable<Pirate> interface.
publicclassPirate : IEquatable<Pirate>
{
publicint Id { get; }
publicstring Name { get; }
public Pirate(int id, string username)
{
Id = id;
Name = username;
}
bool IEquatable<Pirate>.Equals(Pirate? other)
{
Console.WriteLine($"IEquatable Equals: {this.Name} vs {other.Name}");
returnthis.Id == other.Id;
}
publicoverridebool Equals(object obj)
{
Console.WriteLine($"Override Equals {this.Name} vs {(obj as Pirate).Name}");
return Equals(obj as Pirate);
}
publicoverrideint GetHashCode()
{
Console.WriteLine($"GetHashCode {this.Id}");
return (Id).GetHashCode();
}
}
The IEquatable interface forces you to implement the Equals method. So, now we have two implementations of Equals (the one for IEquatable and the one that overrides the default implementation). Which one is correct? Is the GetHashCode really used?
Let’s see what happens in the next screenshot:
As you could’ve imagined, the Equals method called in this case is the one needed to implement the IEquatable interface.
Please note that, as we don’t need to use the custom comparer, the HashSet initialization becomes:
HashSet<Pirate> hashSet = new HashSet<Pirate>();
What has the precedence: IEquatable or IEqualityComparer?
What happens when we use both IEquatable and IEqualityComparer?
Let’s quickly demonstrate it.
First of all, keep the previous implementation of the Pirate class, where the equality check is based on the Id property:
publicclassPirate : IEquatable<Pirate>
{
publicint Id { get; }
publicstring Name { get; }
public Pirate(int id, string username)
{
Id = id;
Name = username;
}
bool IEquatable<Pirate>.Equals(Pirate? other)
{
Console.WriteLine($"IEquatable Equals: {this.Name} vs {other.Name}");
returnthis.Id == other.Id;
}
publicoverrideint GetHashCode()
{
Console.WriteLine($"GetHashCode {this.Id}");
return (Id).GetHashCode();
}
}
Now, create a new IEqualityComparer where the equality is based on the Name property.
Now we have custom checks on both the Name and the Id.
It’s time to add a new pirate to the list, and initialize the HashSet by passing in the constructor an instance of PirateComparerByName.
List<Pirate> mugiwara = new List<Pirate>()
{
new Pirate(1, "Luffy"),
new Pirate(2, "Zoro"),
new Pirate(3, "Nami"),
new Pirate(4, "Sanji"), // Id = 4new Pirate(5, "Chopper"), // Name = Choppernew Pirate(6, "Robin"),
new Pirate(4, "Duval"), // Id = 4new Pirate(7, "Chopper") // Name = Chopper};
HashSet<Pirate> hashSet = new HashSet<Pirate>(new PirateComparerByName());
foreach (var pirate in mugiwara)
{
hashSet.Add(pirate);
}
We now have two pirates with ID = 4 and two other pirates with Name = Chopper.
Can you foresee what will happen?
The checks on the ID are totally ignored: in fact, the final result contains both Sanji and Duval, even if their IDs are the same. The custom IEqualityComparer has the precedence over the IEquatable interface.
The Rule of 114 is a quick way to estimate how long it will take to triple your money with compound interest. The idea is simple: divide 114 by the annual interest rate (in %), and you will get an approximate answer in years.
If you earn 10% annually, the time to triple your money is approximately: 114/10=11.4 years.
Similarly, the Rule of 144 works for quadrupling your money. Divide 144 by the annual interest rate to estimate the time.
At 10% annual growth, the time to quadruple your money is: 144/10=14.4 years
Why Do These Rules Work?
These rules are approximations based on the exponential nature of compound interest. While they are not perfectly accurate for all rates, they are great for quick mental math, especially for interest rates in the 5–15% range. While the rules are convenient, always use the exact formula when accuracy matters!
Exact Formulas?
For precise calculations, use the exact formula based on logarithms:
To triple your money:
To quadruple your money:
These rules for 4x or 3x can be summarized with the following python formula:
defexact_time_for_multiplier(n,rate_percent):
rate_decimal=rate_percent/100
returnmath.log(n)/math.log(1+rate_decimal)
# Example: Growing your money 10x
n=10
rate=8# 8% annual interest
exact_time=exact_time_for_multiplier(n,rate)
print(f“Exact time to grow money {n}x at {rate}% interest: {exact_time:.2f} years”)
Generally, these rules are explained a bit into more details in the video, below: