https://community.libre.space/t/observation-14707468-marina-98293/15148
> Download as satnogs.csv (2026-08-07 09:37:xx UTC)
> Take the parts starting with the string: 87 BF 54
> there are missing lines for the sequences: 19 13 00, 19 15 00, 19 16 80, 19 18 80
> there are repair parts starting with string 87 BF 94 and 87 BF D4 to replace the
> missing lines / sequences.
> (Details are under analysis.)
> right_sequence.txt
> only_payload.txt
$ cat only_payload.txt | tr -d ' ' > space_cut.txt
$ cat space_cut.txt | tr -d '\r\n' > oneline.txt
$ cat oneline.txt | xxd -r -p > marina.jpg
Marina jpg Automatic experiment #1
The process of generating JPG images has now become almost entirely automated. I conducted
experiments focusing on lines starting with "87BF54" where the total amount of data is small
and confirmed that these methods allow for 100% generation into JPG images. I will explain
the sequence of steps here. Use the most recent satnogs.csv file. It is necessary to perform
a little form of formatting on the intermediate files output from each of the following stages.
----------------------------------------------------------------------------------------------
[extract1.rb] ... Extract lines starting with "87BF54" from satnogs.csv.
> File.open("extract1.txt", "w") do |out|
> File.foreach("satnogs.csv") do |line|
> out.puts line if line.include?("87BF54")
> end
> end
$ ruby extract1.rb > 60811ma1.sh
$ sh 60811ma1.sh
----------------------------------------------------------------------------------------------
[sequence1.rb] ... Rearrange the lines in pairs of "[i]80,[i]00" to match
the area outlined in red in the figure above.
> for i in 0..0x0b2
> printf("grep 87BF5400841B00000007A7CB63A...%02X extract1.txt | head -2 >> sequence1.txt\n", i)
> end
$ ruby sequence1.rb > 60811ma2.sh
$ sh 60811ma2.sh
----------------------------------------------------------------------------------------------
[reverse1.rb] ,,, Swap the top and bottom lines of each pair changing from
"[i]80,[i]00" to "[i]00,[i]80". Check the [i] sequences for all lines.
In particular, verify the presence of FFD8 in the first line and FFD9
in the last line. After making the corrections, rename the file from
"sequence2.txt" to "reverse1.txt" and save it.
> lines = File.readlines("sequence1.txt")
> File.open("sequence2.txt", "w") do |file|
> lines.each_slice(2) do |pair|
> pair.reverse_each { |line| file.print line }
> end
> end
$ ruby reverse1.rb > 60811ma3.sh
$ sh 60811ma3.sh
----------------------------------------------------------------------------------------------
[reverse2.rb] ... Trim the beginning and end of each line, and extract the core data
range from all lines. The first letter in the first line is FFD8,
and the last letter in the last line is FFD9.
> File.open("reverse2.txt", "w") do |out|
> File.foreach("reverse1.txt") do |line|
> out.puts line.chomp[58, 256]
> end
> end
$ ruby reverse2.rb > 60811ma4.sh
$ sh 60811ma4.sh
----------------------------------------------------------------------------------------------
[one_line1.txt] ... Edit the FFD8~FFD9 range in reverse2.txt into one single line and convert it.
$ tr -d '\n' < reverse2.txt > one_line1.txt
$ cat one_line1.txt | xxd -r -p > marina.jpg
Marina jpg Automatic experiment #2
Correcting each output file, specifically, formatting "sequence16.txt" into "reverse17.txt",
required an enormous amount of time. The following is a semi-automated method, but fully
automating it would likely be nearly impossible.
----------------------------------------------------------------------------------------------
[extract11.rb] ... Extract lines starting with "2026-08-08 23:" in satnogs.csv
> File.open("extract11.txt", "w") do |out|
> File.foreach("satnogs.csv") do |line|
> out.puts line if line.include?("2026-08-08 23:")
> end
> end
$ ruby extract11.rb > 60816ma1.sh
$ sh 60816ma1.sh
----------------------------------------------------------------------------------------------
[extract12.rb] ... Extract lines starting with "DUS-NORD-UHF-JO31jg" in extract11.txt
> File.open("extract12.txt", "w") do |out|
> File.foreach("extract11.txt") do |line|
> out.puts line if line.include?("DUS-NORD-UHF-JO31jg")
> end
> end
$ ruby extract12.rb > 60816ma2.sh
$ sh 60816ma2.sh
----------------------------------------------------------------------------------------------
[extract13.txt] ... Extract incloding lines from FFD8 to FFD9 in extract12.txt
> Extract time stamp from "2026-08-08 23:00:36" to "2026-08-08 23:01:33"
> Insert 0000 and 0080 into the bottom two lines, respectively.
> Save as extract13.txt
----------------------------------------------------------------------------------------------
[sequence14.rb] ... Rearrange the lines in pairs of "[i]80,[i]00" to match
the area outlined in red in the top figure.
> for i in 0..0x164
> printf("grep 87BBD400841B000000088E2D923...%02X extract13.txt | head -2 >> sequence14.txt\n", i)
> end
$ ruby sequence14.rb > 60816ma3.sh
$ sh 60816ma3.sh
----------------------------------------------------------------------------------------------
[sequence15.txt] ... Fill in the missing parts of "[i]80,[i]00" and save it again with a new name.
----------------------------------------------------------------------------------------------
[reverse16.rb] ,,, Swap the top and bottom lines of each pair changing from
"[i]80,[i]00" to "[i]00,[i]80". Check the [i] sequences for all lines.
In particular, verify the presence of FFD8 in the first line and FFD9
in the last line. After making the corrections, rename the file from
"sequence16.txt" to "reverse17.txt" and save it.
> lines = File.readlines("sequence15.txt")
> File.open("sequence16.txt", "w") do |file|
> lines.each_slice(2) do |pair|
> pair.reverse_each { |line| file.print line }
> end
> end
$ ruby reverse16.rb > 60816ma4.sh
$ sh 60816ma4.sh
----------------------------------------------------------------------------------------------
[reverse17.txt] ... Add the necessary corrections to sequence16.txt.
----------------------------------------------------------------------------------------------
[reverse18.rb] ... Trim the beginning and end of each line, and extract the core data
range from all lines. The first letter in the first line is FFD8,
and the last letter in the last line is FFD9.
> File.open("reverse18.txt", "w") do |out|
> File.foreach("reverse17.txt") do |line|
> out.puts line.chomp[58, 256]
> end
> end
$ ruby reverse18.rb > 60816ma5.sh
$ sh 60816ma5.sh
----------------------------------------------------------------------------------------------
[one_line19.txt] ... Edit the FFD8~FFD9 range in reverse18.txt into one single line and convert it.
$ tr -d '\n' < reverse18.txt > one_line19.txt
$ cat one_line19.txt | xxd -r -p > marina.jpg
----------------------------------------------------------------------------------------------
I asked ChatGPT the following. It might be possible to fully automate it in the future.
-----------------------------------------------------------------------------
[Q1]
How can I use Ruby to extract and save lines that contain multiple specific strings?
[A1]
keywords = ["apple", "orange"]
File.open("output.txt", "w") do |out|
File.foreach("input.txt") do |line|
if keywords.all? { |keyword| line.include?(keyword) }
out.write(line)
end
end
end
-----------------------------------------------------------------------------
[Q2]
How can I use Ruby to search through lines, identify those containing a specific string
between the 20~23 position, sort them based on that sequence, and save the result?
0000
0080
0100
0180
0200
0280
0300
0380
[A2]
order = %w[
0000
0080
0100
0180
0200
0280
0300
0380
]
rank = order.each_with_index.to_h
lines = File.readlines("input.txt", chomp: true)
sorted = lines
.select { |line| rank.key?(line[19, 4]) }
.sort_by { |line| rank[line[19, 4]] }
File.write("output.txt", sorted.join("\n") + "\n")
-----------------------------------------------------------------------------
Note: Since Ruby strings are 0-indexed,
line[19, 4]
retrieves 4 characters starting from the 20th characte, so the 20~23 position.
-----------------------------------------------------------------------------
[Q3]
How can I use Ruby to search through lines, identify the characters from the 51~54
position based on a specific pattern, and save the matching lines keeping only one
instance of each and arranging them in the order they appear?
0000
0080
0100
0180
0200
0280
0300
0380
:
:
EE00
EE80
[A3]
# Value to sort
keys = (0x0000..0xEE80).step(0x80).map { |n| format("%04X", n) }
lines = File.readlines("input.txt", chomp: true)
# Extract and classify characters 51 through 54.
groups = Hash.new { |h, k| h[k] = [] }
lines.each do |line|
key = In Ruby, counting starts at 0, so 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("output.txt", "w") do |f|
result.each do |line|
f.puts line
end
end