diff --git a/src/LibHac/Fs/Common/Range.cs b/src/LibHac/Fs/Common/Range.cs
new file mode 100644
index 00000000..41a55d9a
--- /dev/null
+++ b/src/LibHac/Fs/Common/Range.cs
@@ -0,0 +1,66 @@
+// ReSharper disable InconsistentNaming CheckNamespace
+
+using System;
+using LibHac.Diag;
+
+namespace LibHac.Fs;
+
+///
+/// Represents a contiguous range of offsets in a piece of data.
+///
+/// Based on FS 13.1.0 (nnSdk 13.4.0)
+public readonly struct Range : IEquatable, IComparable
+{
+ public readonly long Offset;
+ public readonly long Size;
+
+ public Range(long offset, long size)
+ {
+ Offset = offset;
+ Size = size;
+ }
+
+ public bool Contains(Range range)
+ {
+ return Offset <= range.Offset &&
+ range.Offset + range.Size <= Offset + Size;
+ }
+
+ public bool HasIntersection(Range range)
+ {
+ return Offset + Size > range.Offset &&
+ range.Offset + range.Size > Offset;
+ }
+
+ public bool IsAdjacent(Range range)
+ {
+ return Offset + Size == range.Offset ||
+ range.Offset + range.Size == Offset;
+ }
+
+ public Range MakeMerge(Range range)
+ {
+ Assert.SdkAssert(HasIntersection(range) || IsAdjacent(range));
+
+ long endOffsetThis = Offset + Size;
+ long endOffsetOther = range.Offset + range.Size;
+
+ long startOffsetMerged = Math.Min(Offset, range.Offset);
+ long endOffsetMerged = Math.Max(endOffsetThis, endOffsetOther);
+
+ return new Range(startOffsetMerged, endOffsetMerged - startOffsetMerged);
+ }
+
+ // Equality is done with only the offset because this type is mainly used with RangeSet
+ // which will never contain multiple ranges with the same offset.
+ public static bool operator <(Range lhs, Range rhs) => lhs.Offset < rhs.Offset;
+ public static bool operator >(Range lhs, Range rhs) => lhs.Offset > rhs.Offset;
+ public static bool operator ==(Range lhs, Range rhs) => lhs.Offset == rhs.Offset;
+ public static bool operator !=(Range lhs, Range rhs) => lhs.Offset != rhs.Offset;
+
+ public bool Equals(Range other) => Offset == other.Offset;
+
+ public override bool Equals(object obj) => obj is Range other && Equals(other);
+ public int CompareTo(Range other) => Offset.CompareTo(other.Offset);
+ public override int GetHashCode() => Offset.GetHashCode();
+}
\ No newline at end of file