BMTLab.ImeiType
1.0.0
dotnet add package BMTLab.ImeiType --version 1.0.0
NuGet\Install-Package BMTLab.ImeiType -Version 1.0.0
<PackageReference Include="BMTLab.ImeiType" Version="1.0.0" />
paket add BMTLab.ImeiType --version 1.0.0
#r "nuget: BMTLab.ImeiType, 1.0.0"
// Install BMTLab.ImeiType as a Cake Addin #addin nuget:?package=BMTLab.ImeiType&version=1.0.0 // Install BMTLab.ImeiType as a Cake Tool #tool nuget:?package=BMTLab.ImeiType&version=1.0.0
BMTLab.ImeiType
BMTLab.ImeiType is a .NET library
that provides a strongly-typed IMEI (International Mobile Equipment Identity) readonly struct
.
It offers a simple API for validation, parsing, and generating IMEI numbers.
This package helps improve type safety, reduce errors, and handle IMEI values consistently in your applications.
Supported Platforms
-.NET 9.0
,8.0
,7.0
,6.0
, and
-.NET Standard 2.1
Installation
Install via NuGet:
dotnet add package BMTLab.ImeiType
Or edit your .csproj
:
<PackageReference Include="BMTLab.ImeiType" Version="1.0.0" />
Features
public readonly struct Imei
: IEquatable<Imei>,
IEqualityOperators<Imei, Imei, bool>, // .NET 7.0 or greater
ISpanParsable<Imei>, // .NET 7.0 or greater
IUtf8SpanParsable<Imei> // .NET 8.0 or greater
- Strongly-Typed Imei Struct
Stores the IMEI number (long
) internally.
Providing high-performance methods and approaches with minimized memory allocation,
as well as a set of specific tweaks and interface implementations for each supported platform.
- Multiple Parsing And Creation Options
Imei.Parse(...)
and Imei.TryParse(...)
from long
, string
, ReadOnlySpan<char>
, or ReadOnlySpan<byte> (UTF-8)
with overload options.
- Random IMEI Generation
Imei.NewRandomImei(); // Creates a secure random IMEI using secure RandomNumberGenerator.
Imei.NewRandomImei(int seed); // Useful for testing or reproducible results.
- Detailed IMEI Parts & Constants
Imei.Tac; // Type Allocation Code ('35', e.g.)
Imei.Fac; // Final Assembly Code ('630348', e.g.)
Imei.Snr; // Serial Number ('991680', e.g.)
public const int Length = 15;
// Minimum and maximum allowed value of IMEI number
public const long MinValue = 00_000000_000001_9;
public const long MaxValue = 99_999999_999999_4;
Conversions
✅ Implicit conversion to
string
,ReadOnlySpan<char>
, andReadOnlySpan<byte>
;✅ Explicit conversion from
long
,string
, or spans;✅ Helper methods:
ToInt64()
,ToReadOnlySpan()
andToUtf8()
and vice versaToImei()
.Validation
Checks values of different types to see if the value is a valid IMEI (via Luhn checksum).
Quick Example
Initialization
using BMTLab.ImeiType;
// This line shall not compile
Imei illegal = new Imei();
// Create an IMEI from a long (int64)
Imei imei1 = new Imei(356303489916807);
// From string or char arrays (or spans)
Imei imei2 = new Imei("356303489916807");
Imei imei3 = new Imei("356303489916807".AsSpan());
Imei imei4 = new Imei(['3', '5', '6', '3', '0', '3', '4', '8', '9', '9', '1', '6', '8', '0', '7']);
// From UTF-8 text
Imei imei5 = new Imei("356303489916807"u8);
Imei imei6 = new Imei([0x33, 0x35, 0x36, 0x33, 0x30, 0x33, 0x34, 0x38, 0x39, 0x39, 0x31, 0x36, 0x38, 0x30, 0x37]);
[!IMPORTANT] Because
Imei
is areadonly struct
, a parameterless constructor cannot be fully removed. We therefore mark the empty constructor with[Obsolete(error: true)]
to prevent its usage.
Alternatively, you can cast values into an Imei
:
using BMTLab.ImeiType;
Imei imei1 = (Imei) 356303489916807;
Imei imei2 = (Imei) "356303489916807";
Imei imei3 = (Imei) "356303489916807".AsSpan();
Imei imei4 = (Imei) new char[] {'3', '5', '6', '3', '0', '3', '4', '8', '9', '9', '1', '6', '8', '0', '7'};
Imei imei5 = (Imei) "356303489916807"u8;
Imei imei6 = (Imei) stackalloc byte[] { 0x33, 0x35, 0x36, 0x33, 0x30, 0x33, 0x34, 0x38, 0x39, 0x39, 0x31, 0x36, 0x38, 0x30, 0x37 };
Or parse it, for example:
using BMTLab.ImeiType;
bool canBeParsedAndValid = Imei.TryParse(356303489916807, out Imei parsedImei);
// ...and so on
Validation
By default,
every new Imei(...)
is validated to ensure the 15-digit number is correct,
according to the IMEI specification (using a Luhn checksum).
To avoid getting a FormatException
during creation, you can use one of these overloads to check validity
(return boolean):
IsValid(long)
IsValid(ReadOnlySpan<byte>)
IsValid(ReadOnlySpan<char>)
IsValid(string?)
IsValid(Imei)
- in caseImei
was created viadefault(Imei)
, which unfortunately we cannot restrict.
[!TIP] If you are sure that the passed value will never be wrong, you can disable the check on creation and improve performance a bit. To do this, set this static property:
/* (`true` by default) can be set to `false` to skip validation on creation (use carefully) */
Imei.ShouldValidateWhileInitialization = false;
[!IMPORTANT] but use this at your own risk as it will affect the behavior globally.
Conversion
Where a primitive type is expected, the IMEI type itself can easily be used, typically:
using BMTLab.ImeiType;
var imei = (Imei) 356303489916807;
string imeiAsString = imei;
ReadOnlySpan<char> imeiAsCharSpan = imei;
ReadOnlySpan<byte> imeiAsUtf8Text = imei;
/* Conversion to long is explicit, it is necessary to avoid ambiguous type reference when printing e.g. */
long imeiAsLong = (long) imei;
Console.WriteLine($"IMEI value: {imei}"); //> "IMEI value: 015434904561440", e.g.
Equality check
using BMTLab.ImeiType;
var imeiA = (Imei) "356303489916807";
var imeiB = (Imei) "356303489916807";
Console.WriteLine(imeiA == imeiB); //> true
Console.WriteLine(imeiA.Equals(imeiB)); //> true
Generating a new random IMEI
using BMTLab.ImeiType;
var newImeiA = Imei.NewRandomImei(seed: 42); // By using System.Random. Useful for testing or reproducible results
var newImeiB = Imei.NewRandomImei(); // By using System.Security.Cryptography
WriteLine($"Random IMEI (with seed): {newImeiA}");
WriteLine($"Random IMEI (secure, but slower a bit): {newImeiB}");
Future Ideas
I plan to add a couple of new optional extension projects for ImeiType
,
such as integration with System.Text.Json
and EF Core
.
Notice
This project uses the dependency FluentAssertions
version 7.0.0
,
which is distributed under a license other than
MIT — Apache 2.0 —
but the ImeiType
project does not include any binary files or source code
of FluentAssertions.
Contributing
Please feel free to fork this, contribute or let me know if you find a bug. Any ideas for improvement are always welcome as well 😇
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 45 | 2/7/2025 |
Release