Skip to content

Instantly share code, notes, and snippets.

@endowdly
Created November 19, 2021 17:18
Show Gist options
  • Save endowdly/3532c938339498702a47e041693bbb4d to your computer and use it in GitHub Desktop.
Save endowdly/3532c938339498702a47e041693bbb4d to your computer and use it in GitHub Desktop.
Like Format-Hex but faster (probably not better though...)
namespace Endowdly.Commands
{
using System;
using System.Collections;
using System.IO;
using System.Management.Automation;
using System.Text;
[Cmdlet(VerbsCommon.Format, Noun, DefaultParameterSetName = NotAsHexParameterSet)]
public class FormatIntegerCommand : PSCmdlet
{
private const string Noun = "Integer";
private const string Space = " ";
private const string ReverseAlias = "SwapEndianness";
private const string AsHexParameterSet = "AsHex";
private const string NotAsHexParameterSet = "NotAsHex";
private const string Newline = "\n";
private const char Zero = '0';
[Parameter(
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public string Path { get; set; }
[Parameter(ParameterSetName = AsHexParameterSet)]
public SwitchParameter AsHex
{
get { return asHex; }
set { asHex = value; }
}
[Parameter]
[Alias(ReverseAlias)]
public SwitchParameter Reverse
{
get { return reverse; }
set { reverse = value; }
}
[Parameter(ParameterSetName = NotAsHexParameterSet)]
public SwitchParameter FlipOutput
{
get { return flip; }
set { flip = value; }
}
private bool asHex;
private bool reverse;
private bool flip;
protected override void ProcessRecord()
{
ProviderInfo provider;
Func<string, string> flipIfFlip = s => flip ? s.Reverse() : s;
var filePath = GetResolvedProviderPathFromPSPath(Path, out provider)[0];
var fi = new FileInfo(filePath);
var oh = flipIfFlip(asHex ? Data.HexOverHeader : Data.BinaryOverHeader);
var h = flipIfFlip(asHex ? Data.HexHeader : Data.BinaryHeader);
// Header information
WriteObject(fi.Name.PadLeft(40));
WriteObject(Newline);
WriteObject(oh);
WriteObject(h);
WriteObject(Newline);
var fileBytes = File.ReadAllBytes(fi.FullName);
var remBytes = fileBytes.Length % 4;
var bytes = new byte[fileBytes.Length + (4 - remBytes)];
fileBytes.CopyTo(bytes, 0);
var numDWords = bytes.Length / 4;
var rowCounter = 0;
var toBase = asHex ? 16 : 2;
var dword = new byte[4];
for (int i = 0; i < numDWords; i++)
{
for (int j = 0; j <= 3; j++)
{
dword[j] = bytes[(i * 4) + j];
}
if (reverse) Array.Reverse(dword);
var sb = new StringBuilder();
var bits = new BitArray(dword);
for (var b = 0; b <= 3; b++)
{
if (asHex)
{
var s = Convert.ToString(dword[b], toBase).PadLeft(2, Zero);
sb.Append(s).Append(Space);
}
else
{
for (var bit = 0; bit < 8; bit++)
{
var idx = (b << 3) + bit;
var v = bits[idx] ? 1 : 0;
sb.Append(v).Append(Space);
if (bit == 3) sb.Append(Space); // seperate on the nibbles too
}
sb.Append(Space);
}
}
var output = flipIfFlip(sb.ToString().TrimEnd());
var lineNumber = rowCounter.ToString().PadLeft(3, Zero).PadRight(4);
rowCounter++;
WriteObject(output.Insert(0, lineNumber));
}
}
}
internal static class Data
{
private const string Space = " ";
internal const string FileNotFound = "File Not Found";
internal const string CannotBeZero = "Parameter cannot be zero";
internal const string HexOverHeader = " ";
internal const string HexHeader = " 00 01 02 03 ";
internal static string BinaryOverHeader
{
get
{
var sb = new StringBuilder(" ");
for (int i = 0; i <= 31; i++)
{
if (i % 10 == 0)
{
sb.Append(i/10);
}
else
{
sb.Append(Space);
}
sb.Append(Space);
if ((i + 1) % 4 == 0) sb.Append(Space);
}
sb.Append(" ");
return sb.ToString();
}
}
internal static string BinaryHeader
{
get
{
var sb = new StringBuilder(" ");
for (int i = 0; i <= 31; i++)
{
sb.Append(i % 10);
sb.Append(Space);
if ((i + 1) % 4 == 0) sb.Append(Space);
}
sb.Append(" ");
return sb.ToString();
}
}
}
internal static class Helpers
{
// TODO: Needs work --rjd @low
// internal static byte[] SwapEndianness(byte[] a)
// {
// var b = new byte[4];
// var b0 = (a[0] >> 0) & 0xff;
// var b1 = (a[1] >> 8) & 0xff;
// var b2 = (a[2] >> 16) & 0xff;
// var b3 = (a[3] >> 24) & 0xff;
// b[0] = (byte)(b0 << 24);
// b[1] = (byte)(b1 << 16);
// b[2] = (byte)(b2 << 8);
// b[3] = (byte)(b3 << 0);
// return b;
// }
// This is cheap and easy but not unicode safe.
internal static string Reverse(this string s)
{
var a = s.ToCharArray();
Array.Reverse(a);
return new string(a);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment