ls /asapon/blog

基本tech、時々多趣味

新年あけおめ縦走してきました [後編]

つづきです。

前編はこちら

景信山〜小仏城山

f:id:asaponseiten:20200103143740j:plain f:id:asaponseiten:20200103143941j:plain

絶景を見ながら景信山をあとにします。

f:id:asaponseiten:20200103143820j:plain

台風の影響で小仏ルートが止まっています。登山前に調べた限りでも、復旧の見込みは立っていない模様。
陣場山〜高尾山は、至るところにエスケープがあるため挑戦しやすいのですが、バス停までの道が閉ざされているので、若干難易度があがっている気がします。

f:id:asaponseiten:20200103143857j:plain

通行止めルート。
ここから稜線特有のアップダウンが出てきます。足取りが遅くなっている方も増えてきたので、「次でちょっと休もう」と考え始めたときでした。

小仏城山

f:id:asaponseiten:20200103144016j:plain

小仏城山に着。高尾山から来た観光客も合わさり、なかなか賑やかになっていました。格好がジーパンなので露骨に分かりますね。 休憩がてら小腹が空いていたので、おでんを買おうと決めていました!

f:id:asaponseiten:20200103160136j:plain

ただのおでんでも、疲労と景色が最高のスパイスになって美味しい...

小仏城山〜高尾山

f:id:asaponseiten:20200103163523j:plain

こういう稜線良いですよね。整備されすぎてる感じもありますが。
丹沢の縦走もしたいなぁ。。

f:id:asaponseiten:20200103162953j:plain

展望台へ。丹沢山地がかっこいい!

f:id:asaponseiten:20200103162913j:plain

そしてとうとう五号路に到着!
この前後で長い階段があるので、気合入れて登りましょう。ここを乗り越えたらゴールはもう目の前です!

高尾山

f:id:asaponseiten:20200103163443j:plain

f:id:asaponseiten:20200103163705j:plain

高尾山に着きました。
頂上の混み具合は土日並だったので、あまり正月三が日という感じではありませんでした。

f:id:asaponseiten:20200103172055j:plain

休憩も取りましたが、だいぶ余裕を持ってゴールできた気がします。
ベースタイムは5時間でした。

f:id:asaponseiten:20200103163351j:plain

f:id:asaponseiten:20200103163606j:plain

f:id:asaponseiten:20200103163742j:plain

薬王院の混み具合を横目に見ながらお団子休憩。

帰りは一号路から、裏高尾ルートを通って、JR高尾駅に向かいました。

おわりに

新年早々、目標だった陣場山〜高尾山の縦走ができて最高です!
今年の夏は日本アルプスも行きたいと思っているので、身体鍛えて頑張ります!

新年あけおめ縦走してきました [前編]

明けましておめでとうございます!
昨日は初詣も兼ねて、念願だった陣場山から高尾山の縦走ルートを歩いてきました。台風の影響で行けてなかったのですが、去年の12月24日にバスが通るようになったので早速。
駄文ですが、当時の空気感を知ってもらえればという感じで書いていきたいと思います。

陣場

f:id:asaponseiten:20200103121942j:plain

めっちゃ晴天でした!かなり寒かったのですが、気持ちよく登れそうです。

f:id:asaponseiten:20200103122649j:plain

最初は舗装された道を登りますが、10分ほどで普通の登山道に合流します。新ハイキングルートという名前でした。
登り続けると途中で急登にあたります。鍋割山のような感じの斜め移動で、ぜぇぜぇ言いながらペースを守って上がっていきます。

f:id:asaponseiten:20200103123057j:plain

登頂しました。ベースタイムは90分でしたが、60分で着。途中雪が溶けて泥道のようになっているところがあり、この時期は泥除け必須だな...と反省。

f:id:asaponseiten:20200103123738j:plain

周りの景色が素晴らしかったです。冬独特の透き通った感じも良く、疲れが吹き飛びます。遠くに富士山も見えました!

陣場山〜景信山

f:id:asaponseiten:20200103124253j:plain

若干お腹は空いていたのですが、景信山で食べようと思いすぐに出発。
サンドイッチも買ってあるし、なんとかなるだろうという読み。

f:id:asaponseiten:20200103124634j:plain

f:id:asaponseiten:20200103124959j:plain

稜線は木々が多く若干景観が悪い。特に高い山でもないので仕方ないのかなという感覚。
ただ道はしっかり整備されているので、歩いていて安心感が凄いです。難易度が高い山だと、危ない縦走もあると聞くので、私みたいな初心者は安心して歩けます。ここらでサンドイッチを食べました。

f:id:asaponseiten:20200103125703j:plain

この前の台風の影響でしょうか。。二ヶ月ほど経っていますが、今だに倒木が残っているようです。特に危険もありませんが、一応注意して歩いていきます。

景信山

f:id:asaponseiten:20200103130040j:plain

程なくして景信山に着きました。2時間半くらいだと思います。ここで半分くらいなので、少し休憩を取りました。

f:id:asaponseiten:20200103131135j:plain

陣場山のパノラマほどではありませんでしたが、景信山も雄大な景色です。

f:id:asaponseiten:20200103131203j:plain

スカイツリーが高すぎて異質だ。

f:id:asaponseiten:20200103131232j:plain

縦走の記念にバッチを購入しました。こういうのをザックに追加していくのが結構楽しい。Macにシールをペタペタしていくようなものでしょうか。

f:id:asaponseiten:20200103131315j:plain

絶景を片手になめこうどんを食べました。なめこ奥多摩一帯の名物のようです。これがめっちゃ美味しい。。

つづく

こちらから後編へ。

圧縮ファイルのハッシュ値がタイムスタンプによって変わってしまう

どんな問題が起こったのか

中身が同じファイルを、それぞれ圧縮した。
だが、圧縮ファイルのハッシュ値が同じにならなかった。

再現してみる


注意
PCの性能によっては、圧縮処理が一瞬で終わるかもしれません。
そうなると事象の再現ができないため、 sleep 1 のような処理を挟む必要があります。タイムスタンプによる影響を確かめるだけであり、ファイルの中身を変える処理ではないためご容赦ください。


中身が同じファイルを用意します。

ls
foo.txt  hoge.txt
➜ diff hoge.txt foo.txt
➜

念の為、ハッシュ値も同じか確かめる。

➜ irb
>> require 'digest/md5'
=> true
>> Digest::MD5.file('hoge.txt')
=> #<Digest::MD5: 7d54bd30550c55950ec0e7f65d1d53c7>
>> Digest::MD5.file('foo.txt')
=> #<Digest::MD5: 7d54bd30550c55950ec0e7f65d1d53c7>

gzip圧縮します。

require 'zlib'
require 'pathname'

MAC_ONLY_FILE = '.DS_Store'
SKIP_FILE = [MAC_ONLY_FILE, 'test.rb']

Dir.open('.') do |d|
  d.children.each do |child|
    next if SKIP_FILE.include?(child)
    sleep 1 # 事象の再現のために挿入

    path = Pathname.new(child)
    gzfile_path = Pathname.new(File.join(path.dirname, "#{path.basename}.gz"))
    File.open(path, 'r') do |f|
      Zlib::GzipWriter.open(gzfile_path) do |gz|
        f.each_line do |line|
          gz.puts line
        end
      end
    end
  end
end

圧縮ファイルのハッシュ値を確かめてみる。

>> Digest::MD5.file('hoge.txt.gz')
=> #<Digest::MD5: 4c537db81e4240fdeec3638319d6be60>
>> Digest::MD5.file('foo.txt.gz')
=> #<Digest::MD5: 0e83011362f4781e60e7813d3a78a0e3>

合わないぞ。。。

なにが原因だったのか

圧縮時のタイムスタンプが、異なっているのが原因。また圧縮ファイルには、ファイル名とコメントも、gzipファイルのヘッダーに記録されます。
まとめると、圧縮時には以下の情報が含まれることになります。

  • タイムスタンプ情報(atime, ctime, mtime)
  • 圧縮元ファイル名
  • コメント(デフォルトはnull)

ちなみに、atime, ctime, mtimeは、ファイルが持つタイムスタンプの情報です。詳しくはこちらを参考にしてください。

どうやって解決したか

設計と実装に分けて整理します。

設計

以下の仕様を満たす必要があった。

  • 圧縮時のmtimeを、デフォルト値ではなくこちら側で制御する。

Zlib::GzipWriter#=mtimeを呼び出せば大丈夫です。
またmtimeは、UNIX TIMEで設定されています。そのため、実際に圧縮した時刻をUNIX TIMEで与える必要があります。
よって、最終的に仕様は以下のようになります。

  • 圧縮時のmtimeを、デフォルト値ではなくこちら側で制御する。
  • mtimeの設定を、現在時刻のUNIX TIMEにすること。

実装

time モジュールからUNIX TIMEを作り出し、mtimeに代入するだけです。

require 'zlib'
require 'pathname'
require 'time'

MAC_ONLY_FILE = '.DS_Store'
SKIP_FILE = [MAC_ONLY_FILE, 'test.rb']
UNIX_TIME_NOW = Time.now.to_i # UNIX TIME

Dir.open('.') do |d|
  d.children.each do |child|
    next if SKIP_FILE.include?(child)
    sleep 1

    path = Pathname.new(child)
    gzfile_path = Pathname.new(File.join(path.dirname, "#{path.basename}.gz"))
    File.open(path, 'r') do |f|
      Zlib::GzipWriter.open(gzfile_path) do |gz|
        gz.mtime = UNIX_TIME_NOW # mtimeを上書きする
        f.each_line do |line|
          gz.puts line
        end
      end
    end
  end
end

ハッシュ値が同じになっているか確認。

>> Digest::MD5.file('hoge.txt.gz')
=> #<Digest::MD5: 4cf682fe3c756d9225d01d1f74567c6d>
>> Digest::MD5.file('foo.txt.gz')
=> #<Digest::MD5: 4cf682fe3c756d9225d01d1f74567c6d>

大丈夫そうです👍

おわりに

年内最後の記事でした!良いお年を〜!