FiftyOne.Did 4.5.41

Prefix Reserved
dotnet add package FiftyOne.Did --version 4.5.41
                    
NuGet\Install-Package FiftyOne.Did -Version 4.5.41
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FiftyOne.Did" Version="4.5.41" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FiftyOne.Did" Version="4.5.41" />
                    
Directory.Packages.props
<PackageReference Include="FiftyOne.Did" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FiftyOne.Did --version 4.5.41
                    
#r "nuget: FiftyOne.Did, 4.5.41"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FiftyOne.Did@4.5.41
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FiftyOne.Did&version=4.5.41
                    
Install as a Cake Addin
#tool nuget:?package=FiftyOne.Did&version=4.5.41
                    
Install as a Cake Tool

FiftyOne.Did

Strongly-typed .NET parser for the 51Did (51Degrees device identifier) returned by the 51Degrees Cloud service.

Terminology

The 51Did has two layers. The wording below treats them as distinct.

  • The 51Did is the identifier. The whole base64 OWID envelope (version, domain, date, payload, signature). It changes byte-for-byte every time the cloud issues one, even for the same inputs, because the date and signature change with each call.
  • The probabilistic value is one of the fields inside the payload (a 32-byte SHA-256 hash). It is stable across reissues for the same device + IP + usage: if two 51Dids were issued for the same inputs, their probabilistic values are equal even though the wrapping identifiers differ.

Comparing two browsers means comparing the probabilistic values carried inside their identifiers, never the identifiers themselves. Calling either layer "the identifier" without qualification leads to incorrect comparisons; calling the inner field "the probabilistic identifier" is the same conflation in a different costume.

Payload layout

Offset Length Field Type
0 1 Flags uint8 usage-flags bit-mask
1 4 LicenseId uint32 (little-endian)
5 32 Hash 32 bytes, SHA-256 probabilistic value

FodId inherits from Owid.Client.Model.Owid (see SWAN-community/owid-dotnet), so a FodId instance behaves as an OWID for all OWID-level concerns (domain, date, payload bytes, signature, base64 round-tripping) and adds strongly-typed accessors for the three 51Did payload fields on top.

Usage

using FiftyOne.Did.Model;

var fodId = new FodId(base64FromCloudService);

byte    flags     = fodId.Flags;
uint    licenseId = fodId.LicenseId;
byte[]  hash      = fodId.Hash;        // 32-byte probabilistic value

// Inherited OWID-level fields.
string   domain   = fodId.Domain;
DateTime date     = fodId.Date;

// Inherited OWID-level operations.
bool     verified = await fodId.VerifyAsync(publicKey);
string   roundTrip = fodId.AsBase64();

Comparing two 51Dids

var a = new FodId(idprobglobalA);
var b = new FodId(idprobglobalB);

// Wrapper bytes (Domain, Date, Signature) ARE different; the
// identifier itself is not stable across reissues:
bool sameDate = a.Date == b.Date;                           // false
bool sameSig  = a.Signature.SequenceEqual(b.Signature);     // false

// The probabilistic value inside the payload IS stable; this is
// what you actually compare:
bool sameValue = a.Hash.SequenceEqual(b.Hash);              // true

Use FodId.Hash as the cache / dedup key. The same value means the same browser instance under the same usage policy on the same License Key (for idproblic) or across all callers (for idprobglobal).

Non-goals

  • Signature verification on construction. Constructing a FodId does not check the signature. Call VerifyAsync (inherited from Owid) when needed.
  • Construction of new 51Dids. This is a parser. New 51Dids are issued by the 51Degrees cloud / on-premise hashing engines.

See also

  • https://github.com/SWAN-community/owid-dotnet, OWID envelope library this package builds on.
  • The 51Did inspector on 51degrees.com for a visual breakdown of the same byte layout, with signature verification and a "Live 51d.es v3" sample.
  • The 51Did comparer for a side-by-side, byte-by-byte comparison of two 51Dids that highlights the wrapper-vs-value distinction in action.
Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.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
4.5.41 0 5/27/2026
4.5.40 46 5/25/2026
4.5.39 47 5/25/2026
4.5.38 55 5/22/2026