Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
バイナリ読むのにElixirしてみた
Search
Tomohiko Himura
October 01, 2024
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
バイナリ読むのにElixirしてみた
Tomohiko Himura
October 01, 2024
More Decks by Tomohiko Himura
See All by Tomohiko Himura
Marpでmermaidは簡単だときいたけど
eiel
1
2.7k
アジャイルはさておきMake People Awesomeしたい
eiel
0
230
レビューは最優先にするようにしている
eiel
0
380
再考 Fourkeys メトリクス
eiel
2
730
Test mockをSnapshot testする
eiel
0
190
devenvに入門した
eiel
1
210
関数プログラミングの考え方
eiel
1
400
逆コンウェイ作戦はフィードバックループを作るために 逆向きの流れをつくること (5分版)
eiel
0
550
組織のパフォーマンスを高めるために 第1話 学習と文化
eiel
0
300
Featured
See All Featured
Faster Mobile Websites
deanohume
310
32k
Building the Perfect Custom Keyboard
takai
2
890
Navigating Team Friction
lara
192
16k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
290
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
So, you think you're a good person
axbom
PRO
2
2.2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
The Curious Case for Waylosing
cassininazir
1
550
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
350
Balancing Empowerment & Direction
lara
6
1.3k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
700
Transcript
バイナリ読むのにElixirしてみた 2024-10-01
自己紹介 ひむら ともひこ 最近してること • 音声合成入門
バイナリ解読にElixir
経緯 • PythonとRustで書き込んだ音声ファイルのそれぞれ挙動が違う • スピーカーから片方しか音がでてない • なにが違うのか ◦ 書き込み処理を見比べる ◦
書き込まれたファイルを見比べる
ファイルの中身をみてみるか
None
眠いときだっので 目と脳がきつい
ツールを使おう
$ nix-shell -p sox $ soxi output.wav Input File :
'output.wav' Channels : 1 Sample Rate : 24000 Precision : 25-bit Duration : 00:00:00.00 = 1 samples ~ 0.003125 CDDA sectors File Size : 956k Bit Rate : 32bit Sample Encoding: 32-bit Floating Point PCM
特に問題が見当たらない
自分で書いてみるかー
そういえば Erlangはバイナリのパターンマッチができる
Elixirでやってみるか
その前に基本 << 1 :: 32 >> # => << 0,
0, 0, 1 >> << 1 :: 16 >> # => << 0, 1 >> << 1 :: 8 >> # => << 1 >> << 1 :: 4 >> # => << 1::size(4) >> << 1 :: 2 >> # => << 1::size(2) >> <<1::size(2)>> # => << 1::size(2) >> << 256 :: 32 >> # => << 0, 0, 1, 0 >>
例 真ん中の2byteだけ取り出したい << _::8, a::16, _::8 >> = << 256::32
>> # => <<0, 0, 1, 0>> a # => 1 << _::8, a::16, _ >> = << 512::32 >> # => <<0, 0, 2, 0>> a # => 2
例 文字列に対しても << a::bitstring-8, b::bitstring-16, _ >> = "goro" a
# => “g” b # => “or”
例 文字列2 << a::bitstring-8, 111::8, b::bitstring-16 >> = "goro" a
#=> g b # => ro # 以下のような書き方もできる << a::bitstring-8, ?o, b::bitstring-16 >> = "goro" << a::bitstring-8, “o”, b::bitstring-16 >> = "goro"
例 case def x(v) do case v do << a::bitstring-8,
“o”, b :: bitstring-16 >> -> [a,b] << a ::bitstring-8, “a”, b :: bitstring-8 >> -> [a,b] end end x “goro” # => [“g”, “ro”] x “gao” # => [“g”, “o”]
WAVの構造を確認しながら 書いてみた
filename = Enum.at System.argv, 0 {:ok, data} = File.read filename
<< id :: bitstring-32, chunk_size :: integer-little-32, riff_type :: bitstring-32, rest >> = data IO.puts """ groupID: #{id} churk size: #{chunk_size} byte (filesize #{chunk_size+8}) riff type: #{riff_type} """
case rest do << “fmt “, # 先頭が “fmt “
で始まっていて… format_chunk_size :: integer-little-32, format_tag :: integer-little-16, channel :: unsigned-integer-little-16, sample_per_sec :: integer-little-32, avg_byte_per_sec :: integer-little-32, block_align :: integer-little-16, bits_per_sample :: integer-little-16, _ >> -> IO.puts """ chunkID: fmt format chunk size: #{format_chunk_size} byte format tag: #{format_tag} #{B.tag format_tag} channel: #{B.channel channel} #{channel} sample per sec: #{sample_per_sec} Hz byte per sec: #{avg_byte_per_sec} block align: #{block_align} bits per sample(bitrate): #{bits_per_sample} """ << “fact”, … >> -> # “fact” だったら... end
groupID: RIFF churk size: 956210 byte (filesize 956218) riff type:
WAVE chunkID: fmt format chunk size: 18 byte format tag: 3 IEEE float channel: mono 1 sample per sec: 24000 Hz byte per sec: 96000 block align: 4 bits per sample(bitrate): 32
まとめ
まとめというか振り返り - ErlangVMは通信を得意とするのでビット列を扱いやすいはず - 使いやすそうだった - ビット列をパターンマッチできる - 便利さがわかるところまで触れなかった -
でも、試す良い機会になった - 今回の用途では構造体をつらつら書くのと大差ない感じになってしまった - 別にElixirでなくても簡単にかけただろう - とはいえ、新しい道具を試すのは大切
で問題は解決したのか? • 昨夜書いてみただけなので、まだ解決はしていない
参考文献とか - https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3 E%3E/1-types - 指定できるtypeの確認に -