Skip to content

Instantly share code, notes, and snippets.

@marcinotorowski
Last active December 13, 2021 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcinotorowski/6a51023600160fcceef9ceea341bbc4a to your computer and use it in GitHub Desktop.
Save marcinotorowski/6a51023600160fcceef9ceea341bbc4a to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Otor
{
public class MsixUtils
{
public static string GetPublisherHash(string publisherId)
{
using var sha = HashAlgorithm.Create("SHA256");
var encoded = sha.ComputeHash(Encoding.Unicode.GetBytes(publisherId));
var binaryString = string.Concat(encoded.Take(8).Select(c => Convert.ToString(c, 2).PadLeft(8, '0'))) + '0'; // representing 65-bits = 13 * 5
var encodedPublisherId = string.Concat(Enumerable.Range(0, binaryString.Length / 5).Select(i => "0123456789abcdefghjkmnpqrstvwxyz".Substring(Convert.ToInt32(binaryString.Substring(i * 5, 5), 2), 1)));
return encodedPublisherId;
}
}
}
@marcinotorowski
Copy link
Author

This is a compact algorithm that given a publisher ID calculates its hash for APPX-management purposes.

The algorithm:

  1. Takes an UTF-16 encoded string and calculates its SHA-256 hash
  2. It takes the first 8-bytes of the checksum
  3. For each byte, it converts it to a binary representation (8 characters)
  4. Since this gives 8 x 8 = 64 characters, an extra zero ('0') is added to have a string of a length divisible by 5
  5. Then an algorithm processes the bytes in chunk of 5 characters.
    • For each chunk, the 5-character string is converted to an integer (since 2^5 = 32, it produces a number from 0 to 31).
    • It then takes the n-th character of a string 0123456789abcdefghjkmnpqrstvwxyz (32 letters), where n is the result of the previous operation.
  6. Finally, it joins all produced letters, which gives a string of 13 characters

Steps 5 and 6 actually represent the Douglas Crockford Base32 algorithm

Sample input:

E=marcin@otorowski.com, CN=Marcin Otorowski, O=Marcin Otorowski, S=zachodniopomorskie, C=PL

Output:

zxq1da1qqbeze

Verification:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment