I am trying to make a range of hex from a000000000-afffffffff, but the values are too large for Int32. Getting error Cannot convert value "687194767360" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
Here is the code
(0xa000000000..0xafffffffff|% ToString X10).ToLower()
CodePudding user response:
Since the count of numbers in your range exceeds the capacity of an [int]
value, you won't be able to use an array to hold the entire range of numbers (which is what ..
, the range operator constructs; also, the endpoints themselves must fit into [int]
values) and the [Linq.Enumerable]::Range()
method, which enumerates lazily, unfortunately also only accepts [int]
values.
However, you can implement a streaming solution, where PowerShell creates and emits each "number string" to the pipeline one by one:
$num = 0xa000000000
while ($num -le 0xafffffffff) { ($num ).ToString('x10') }
Note:
While this works, it will be slow.
You won't be able to capture the result as a whole in a collection in memory.
- If you were to stream the output to a file unfiltered, you'd end up with a file 704 GB(!) / 768 GB(!) in size on Unix-like platforms / Windows.
- In-memory, filtering the output into chunk(s) small enough to fit into array(s) is the only option.
CodePudding user response:
Not possible to hold the collection as a whole using System.Array
:
The array size is limited to a total of 4 billion elements, and to a maximum index of 0X7FEFFFFF in any given dimension (0X7FFFFFC7 for byte arrays and arrays of single-byte structures).
Nor using List<T>
:
.NET Framework only: For very large List objects, you can increase the maximum capacity to 2 billion elements on a 64-bit system by setting the enabled attribute of the configuration element to true in the run-time environment.
Assuming you have enough memory to hold 68,719,476,735 elements which I don't think you do :), you could do a list of lists:
$hex = [System.Collections.Generic.List[object]]::new()
$tmp = [System.Collections.Generic.List[string]]::new()
for($i = 0xa000000000; $i -le 0xafffffffff; $i ) {
if($tmp.Count -eq [int]::MaxValue) {
$hex.Add($tmp)
$tmp.Clear()
}
$tmp.Add($i.ToString('x10'))
}
You can use $i.ToString('x10')
or '{0:x10}' -f $i
to produce lower-case hex. See Hexadecimal format specifier (X) for details.