I successfully converted Marina's HEX data into a JPG image on Windows.I performed most
of the work in PowerShell and checked the output files in Geany each time. The file
resulting from sequence22.rb was 100% complete, and the subsequent process of converting
it to JPG was finished in no time, requiring no editing or formatting. The syntax differed
slightly from Linux, and the final step of converting from HEX to binary was quite cumbersome.
In general, the tasks are easier to perform on Linux than on Windows. (-> Summary, Memo)
* Install "Geany," "Ruby," and "Git for Windows" on Windows beforehand.
* Run PowerShell in the "marina" folder.
(Enter to the "marina" folder in File Explorer and type "PowerShell" into the address bar.)
----------------------------------------------------------------------------
[extract20.txt]
Extract lines from the satnogs.csv file that contain "Term 1","Term 2" or "Term 3"
and save the result as extract20.txt.
> Select-String -Path "satnogs.csv" -Pattern "2026-08-08 23:","2026-08-08 22:","2026-08-08 21:" | ForEach-Object { $_.Line } | Set-Content "extract20.txt"
----------------------------------------------------------------------------
[extract21.txt]
Make the following modifications to extract20.txt and save it as extract21.txt.
And insert "0000" at the 51~54th character positions of the lines
containing "FFD8". Change the 51st through 54th character positions of the
lines immediately above them to "0080".
----------------------------------------------------------------------------
[sequence22.txt]
Using Ruby, search "extract21.txt" for lines containing specific numerical values
in 51~54th character positions; sort these lines, keeping only one instance
of each, in the order of those values, and save the result as "sequence22.txt".
0000
0080
0100
0180
0200
0280
0300
0380
:
:
EE00
EE80
----------------------------------------------------------------------------
[sequence22.rb]
# Values to sort
keys = (0x0000..0xEE80).step(0x80).map { |n| format("%04X", n) }
lines = File.readlines("extract21.txt", chomp: true)
# Extract and classify characters 51~54
groups = Hash.new { |h, k| h[k] = [] }
lines.each do |line|
key = line[50, 4] # Since Ruby is 0-indexed, the 51st character = index 50
if keys.include?(key)
groups[key] << line
end
end
# Extract only one line for each key
result = keys.filter_map do |key|
groups[key]&.first
end
File.open("sequence22.txt", "w") do |f|
result.each do |line|
f.puts line
end
end
Save the above in the "marina" folder with the filename "sequence22.rb".
> ruby sequence22.rb > 60819ma1.sh
> .\60819ma1.sh
----------------------------------------------------------------------------
[sequence23.txt]
Check whether the characters at positions 51~54 of "sequence22.txt"
appear in the specified pattern. If that line is missing, replenish
it from another .csv file, then save the result as "sequence23.txt".
0000
0080
0100
0180
0200
0280
0300
0380
:
:
EE00
EE80
----------------------------------------------------------------------------
[sequence24.rb]
Trim the beginning and end of each line, and extract the core data range from
all lines. Verify that the output file begins with FFD8 on the first line and
ends with FFD9 on the last line.
File.open("sequence24.txt", "w") do |out|
File.foreach("sequence23.txt") do |line|
out.puts line.chomp[58, 256]
end
end
> ruby sequence24.rb > 60819ma2.sh
> .\60819ma2.sh
----------------------------------------------------------------------------
[one_line25.txt]
Remove the line breaks from the lines corresponding to FFD8~FFD9 in "sequence24.txt"
to combine them into one single line, and save the result as "one_line25.txt".
> (Get-Content sequence24.txt -Raw) -replace '\r?\n', '' | Set-Content one_line25.txt
----------------------------------------------------------------------------
[marina25.jpg]
Convert "one_line25.txt" which contains FFD8~FFD9 into a JPG image.
> $hex = (Get-Content "one_line25.txt" -Raw).Trim()
> $bytes = for ($i = 0; $i -lt $hex.Length; $i += 2) {[Convert]::ToByte($hex.Substring($i, 2), 16)}
> [System.IO.File]::WriteAllBytes("marina25.jpg", $bytes)
----------------------------------------------------------------------------
Summary
Since characters 21 through 26 of each line in the CSV file indicate the image number
"87BB54" and "87BB94" were specified. As a result, a complete output file with no data
loss was obtained at the stage of the script [sequence32.rb] (sequence32.txt) shown below.
Subsequent processing proceeded directly to the generation of [marina35.jpg], resulting
in a successful conversion to a JPG image completely free of data loss.
Run PowerShell in the "marina" folder.
----------------------------------------------------------------------------
[extract30.txt] ... Extract.
> Select-String -Path "satnogs.csv" -Pattern "87BB54","87BB94" | ForEach-Object { $_.Line } | Set-Content "extract30.txt"
----------------------------------------------------------------------------
[extract31.txt] ... Add "0000" two bytes before FFD8.
----------------------------------------------------------------------------
[sequence32.rb] ... Swap the top and bottom of all lines and
Extract only the single line corresponding to each key.
keys = (0x0000..0xEE80).step(0x80).map { |n| format("%04X", n) }
lines = File.readlines("extract31.txt", chomp: true)
groups = Hash.new { |h, k| h[k] = [] }
lines.each do |line|
key = line[50, 4]
if keys.include?(key)
groups[key] << line
end
end
result = keys.filter_map do |key|
groups[key]&.first
end
File.open("sequence32.txt", "w") do |f|
result.each do |line|
f.puts line
end
end
> ruby sequence32.rb > 60821ma1.sh
> .\60821ma1.sh
----------------------------------------------------------------------------
[sequence33.txt] ... Add missing rows.
----------------------------------------------------------------------------
[sequence34.rb] ... Extract the main data range for all rows.
File.open("sequence34.txt", "w") do |out|
File.foreach("sequence33.txt") do |line|
out.puts line.chomp[58, 256]
end
end
> ruby sequence34.rb > 60821ma2.sh
> .\60821ma2.sh
----------------------------------------------------------------------------
[one_line35.txt] ... Concatenate the data from FFD8 to FFD9 into a single line.
> (Get-Content sequence34.txt -Raw) -replace '\r?\n', '' | Set-Content one_line35.txt
----------------------------------------------------------------------------
[marina35.jpg] ... Convert to a JPG image
> $hex = (Get-Content "one_line35.txt" -Raw).Trim()
> $bytes = for ($i = 0; $i -lt $hex.Length; $i += 2) {[Convert]::ToByte($hex.Substring($i, 2), 16)}
> [System.IO.File]::WriteAllBytes("marina35.jpg", $bytes)
Memo
[#1] on PowerShell
> Select-String -Path "satnogs.csv" -Pattern "87BB54","87BB94" | ForEach-Object { $_.Line } | Set-Content "extract40.txt"
[#2] in Ruby
Add "0000" front FFD8 in extract40.txt and edit it as extract41.txt.
[#3] Save the following as sequence42.rb
keys = (0x0000..0xEE80).step(0x80).map { |n| format("%04X", n) }
lines = File.readlines("extract41.txt", chomp: true)
groups = Hash.new { |h, k| h[k] = [] }
lines.each do |line|
key = line[50, 4]
if keys.include?(key)
groups[key] << line
end
end
result = keys.filter_map do |key|
groups[key]&.first
end
File.open("sequence42.txt", "w") do |f|
result.each do |line|
f.puts line
end
end
[#4] on PowerShell
> ruby sequence42.rb > 60822ma1.sh
> .\60822ma1.sh
[#5] in Ruby
Add the missing lines to sequence42.txt and save it as sequence43.txt.
[#6] Save the following as sequence44.rb
File.open("sequence44.txt", "w") do |out|
File.foreach("sequence43.txt") do |line|
out.puts line.chomp[58, 256]
end
end
[#7] on PowerShell
> ruby sequence44.rb > 60822ma2.sh
> .\60822ma2.sh
[#8] on PowerShell
> (Get-Content sequence44.txt -Raw) -replace '\r?\n', '' | Set-Content one_line45.txt
[#9] on PowerShell
> $hex = (Get-Content "one_line45.txt" -Raw).Trim()
> $bytes = for ($i = 0; $i -lt $hex.Length; $i += 2) {[Convert]::ToByte($hex.Substring($i, 2), 16)}
> [System.IO.File]::WriteAllBytes("marina45.jpg", $bytes)
87BA94,87BAD4, 19 Aug 2026