<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="https://www.w3.org/2005/Atom">
  <title>Stanley Tan</title>
  <id>https://stnly.com/</id>
  <link href="https://stnly.com/"/>
  <link href="https://stnly.com/atom.xml" rel="self"/>
  <updated>2024-09-04T08:00:00+08:00</updated>
  <author>
    <name>Stanley Tan</name>
  </author>
  <entry>
    <title>AES</title>
    <link rel="alternate" href="https://stnly.com/aes/"/>
    <id>https://stnly.com/aes/</id>
    <published>2024-09-04T08:00:00+08:00</published>
    <updated>2024-09-24T14:48:24+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;Recently I had to help decrypt some AES-ECB and AES-CBC offline. This is straight forward in Python as the cryptographic primitives are provided. LLMs are also very useful to generate code for such tasks. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
decrypted_padded_message = cipher.decryptor().update(encrypted_message) + cipher.decryptor().finalize()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <title>fzf and rg</title>
    <link rel="alternate" href="https://stnly.com/fzf-and-rg/"/>
    <id>https://stnly.com/fzf-and-rg/</id>
    <published>2017-10-19T08:00:00+08:00</published>
    <updated>2020-06-03T15:49:29+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;Everyone who works in the shell needs a faster way to get around. fzf and rg in zsh makes for a great combination. I&amp;rsquo;ve been using this setup for a while now and it allows me to jump around my filesystem.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install fzf rg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To install useful key bindings and fuzzy completion:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ $(brew --prefix)/opt/fzf/install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding a couple of lines to .zshrc&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Setting rg as the default source for fzf
export FZF_DEFAULT_COMMAND='rg --files --no-ignore --hidden --follow -g "!{.git,node_modules}/*" 2&amp;gt; /dev/null'

# To apply the command to CTRL-T as well
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;And we&amp;rsquo;re done!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fuzzy history search&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ &amp;lt;crtl&amp;gt; + r
$
   7063  bundle
   7064  bundle exec middleman build
   7065  time bundle exec middleman build
   7066  bundle install
   7067  bundle purge
   7068  bundle --help
   7069  bundle clean
   7070  bundle clean --force
   7071  bundle exec middleman server
   7115  bundle exec middleman
   7161  bundle exec middleman version
   7186  bundle exec middleman server
   7196  bundle install
   7197  bundle exec middleman server
   7265  bundle install
   7266  bundle update
   7267  gem install bundler --pre
   7269  bundle exec middleman build
&amp;gt;  7409  bundle exec middleman server
  129/7409 +S
&amp;gt; bundle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fuzzy file search&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ &amp;lt;ctrl&amp;gt; + t
$
&amp;gt; zshrc
\ 1678/972367
&amp;gt; .zshrc
  .zshrc.zwc
  dotfiles/zsh/.zshrc
  .oh-my-zsh/templates/zshrc.zsh-template
  .oh-my-zsh/plugins/redis-cli/_redis-cli
  .oh-my-zsh/themes/crcandy.zsh-theme
  .oh-my-zsh/plugins/react-native/README.md
  .oh-my-zsh/plugins/react-native/_react-native
  .oh-my-zsh/plugins/react-native/react-native.plugin.zsh
  .oh-my-zsh/plugins/arcanist/README.md
  .oh-my-zsh/plugins/archlinux/README.md
  .oh-my-zsh/plugins/rsync/rsync.plugin.zsh
  .oh-my-zsh/plugins/arcanist/arcanist.plugin.zsh
  .oh-my-zsh/plugins/archlinux/archlinux.plugin.zsh
  .oh-my-zsh/plugins/mercurial/README.md
  .oh-my-zsh/plugins/dircycle/dircycle.plugin.zsh
  .oh-my-zsh/plugins/mercurial/mercurial.plugin.zsh
  .oh-my-zsh/themes/tjkirch.zsh-theme
  .oh-my-zsh/plugins/ember-cli/README.md

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fuzzy directory go to&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ &amp;lt;alt&amp;gt; + c
$
&amp;gt; chrome
| 16635/70115
&amp;gt; Library/Caches/Google/Chrome
  Applications/Chrome Apps.localized
  Library/Caches/Google/Chrome/Default
  Applications/Chrome Canary Apps.localized
  Library/Application Support/Google/Chrome
  Library/Caches/Google/Chrome/Default/Cache
  Library/Application Support/Google/Chrome/pnacl
  Library/Application Support/Google/Chrome Canary
  Library/Caches/Google/Chrome/Default/Media Cache
  Library/Application Support/Google/Chrome/Default
  Library/Application Support/Google/Chrome/Crashpad
  Library/Caches/Google/Chrome/PnaclTranslationCache
  Library/Application Support/Google/Chrome/EVWhitelist
  Library/Application Support/Google/Chrome/PepperFlash
  Library/Application Support/Google/Chrome/ShaderCache
  Library/Application Support/Google/Chrome/WidevineCDM
  Applications/Chrome Canary Apps.localized/app_list.app
  Library/Application Support/Google/Chrome/Crashpad/new
  Library/Application Support/Google/Chrome/OriginTrials
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <title>Crystal on OpenBSD 6.0</title>
    <link rel="alternate" href="https://stnly.com/crystal-on-openbsd/"/>
    <id>https://stnly.com/crystal-on-openbsd/</id>
    <published>2016-12-04T08:00:00+08:00</published>
    <updated>2016-12-05T15:25:55+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;Not the most ideal way to install something on OpenBSD for various reasons. It will be great if there were packages already built for Crystal.&lt;/p&gt;

&lt;h2&gt;Pre-requisites&lt;/h2&gt;

&lt;p&gt;Install bash: &lt;code&gt;doas pkg_add bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OpenBSD comes with a default shell &lt;code&gt;ksh&lt;/code&gt;. Crystal needs bash to run.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ crystal
env: bash: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Installing the binary&lt;/h2&gt;

&lt;p&gt;Download the OpenBSD tarball from &lt;a href="https://github.com/crystal-lang/crystal/releases"&gt;https://github.com/crystal-lang/crystal/releases&lt;/a&gt;. The latest version of Crystal available for OpenBSD is 0.19.4.&lt;/p&gt;

&lt;p&gt;Extract it to where you store user downloaded binaries e.g. &lt;code&gt;/usr/local&lt;/code&gt; or &lt;code&gt;/opt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Link the binary to your path.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ln -sf /usr/local/crystal/bin/crystal /usr/local/bin/crystal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Making sure it works&lt;/h2&gt;

&lt;p&gt;Try running crystal to get the version:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ crystal -v
Crystal 0.19.4 [7f82f79] (2016-10-07)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create a Crystal program and run it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/user/fib.cr
def fibonacci(n)
  return n if n &amp;lt;= 1
  fibonacci(n - 1) + fibonacci(n - 2)
end
puts fibonacci 40
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vim fib.cr
$ crystal build --release fib.cr
$ time ./fib
102334155
    0m00.94s real     0m00.81s user     0m00.01s system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It runs pretty fast on my OpenBSD server. OpenBSD is not particularly fast versus other operating systems, choosing a fast programming language helps speed things up. &lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Remote Shell Setup</title>
    <link rel="alternate" href="https://stnly.com/remote-shell/"/>
    <id>https://stnly.com/remote-shell/</id>
    <published>2016-11-17T08:00:00+08:00</published>
    <updated>2016-12-05T15:25:55+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;I was recently talking about the best way to shell on remote machines. The default way that I&amp;rsquo;ve seen most people run is with just a terminal and SSH. It is simple and very efficient. Nothing to install and configure. All machines will have no issues with that. But once you start requiring a bit more than just running commands, that simple set up will not work well. I needed something that could do all of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain shell session while changing client machines, or networks. I change laptops from personal to work, move across networks from home to office to cafes. It will be annoying to have to reconnect each time instead of the software connecting again once it is able to do so.&lt;/li&gt;
&lt;li&gt;Feel reasonably smooth while typing over high latency or flaky connections as well as while sitting a long distance away from the machine. I travel a lot for work and I can&amp;rsquo;t always sit 5ms away. Getting interrupted while writing due to network instability also reduces productivity which is not ideal.&lt;/li&gt;
&lt;li&gt;Scroll with trackpad.&lt;/li&gt;
&lt;li&gt;Copy/paste from and to the remote shell.&lt;/li&gt;
&lt;li&gt;Colours&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;iTerm2&lt;/h2&gt;

&lt;p&gt;If you are on macOS not using iTerm2, then you are missing out on a lot features that will make your life easier. There&amp;rsquo;s nothing much to do here except to set terminal type reporting to xterm-256color and enable mouse reporting in the settings. This will allow us get colours and to use the trackpad to click and scroll.&lt;/p&gt;

&lt;h2&gt;mosh&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mosh&lt;/code&gt; holds the pieces together. It is a remote terminal application that allows roaming, supports intermittent connectivity, and provides intelligent local echo and line editing of user keystrokes. It&amp;rsquo;s more robust and responsive than SSH, especially over Wi-Fi, cellular, and long-distance links. You&amp;rsquo;ll need to install it on both the client and the server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;macOS: &lt;code&gt;brew install mosh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OpenBSD: &lt;code&gt;pkg_add mosh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Debian/Ubuntu: &lt;code&gt;apt-get install mosh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find installation instructions for other operating systems from &lt;a href="https://mosh.org/#getting"&gt;https://mosh.org/#getting&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;mosh&lt;/code&gt; to be able to work, your server needs to open the usual SSH ports as well as UDP ports between 60000 and 61000. If you have less users on your system, you can open a smaller range.&lt;/p&gt;

&lt;h2&gt;tmux&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tmux&lt;/code&gt; is a terminal multiplexer. It allows the user to switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal. This means that I can be writing text in the first window, chatting on IRC in the second and have a shell prompt on the third. Or split a window into panes and have documentation on the left and write code on the right.&lt;/p&gt;

&lt;p&gt;The configuration file. &lt;code&gt;tmux&lt;/code&gt; can be configured extensively to your liking. Colours, key bindings, status bar information can all be personalised. On the status bar, I have window control to the left and system status to the right. I use it as a simple snapshot to how the system is behaving while I&amp;rsquo;m using it.&lt;/p&gt;

&lt;h2&gt;Putting it all together&lt;/h2&gt;

&lt;p&gt;With the pieces in place, I can just type &lt;code&gt;mosh remote -- tmux a&lt;/code&gt; and get a shell that is just a pleasure to work in.&lt;/p&gt;

&lt;p&gt;This setup allowed me to write and publish this blog post from my laptop while flying through the air at ridiculous altitudes and speeds (41,000ft at 500knots). WiFi in an aircraft has extremely high latency. It takes around 800ms RTT to the nearest Cloudflare PoP. And that is when you are able to successfully connect. &lt;/p&gt;

&lt;p&gt;I am still amazed at how such high latency was not an issue. If this was done on a normal SSH setup, writing this will not be possible.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Roost Laptop Stand</title>
    <link rel="alternate" href="https://stnly.com/roost/"/>
    <id>https://stnly.com/roost/</id>
    <published>2016-03-05T08:00:00+08:00</published>
    <updated>2024-09-24T14:04:05+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;&lt;img src="/images/roost-1-5a96a4c2.jpg" alt="Roost Laptop Stand" /&gt;&lt;/p&gt;

&lt;p&gt;For both work and play, I usually spend 7-8 hours on the laptop each day, some times even more. My work laptop is a 13&amp;quot; Macbook Pro and my personal laptop is a 12&amp;quot; Macbook. I found that crouching over them for such long periods of time caused neck, shoulders and back strain. I knew that it was unsustainable and had to find ways to improve posture before things get worse.&lt;/p&gt;

&lt;p&gt;When I first heard about the Roost, they were discontinuing the production of version 1.0 and there were rumours that version 2.0 was going to be released soon. I waited and backed version 2 when it was announced on Kickstarter.&lt;/p&gt;

&lt;p&gt;Some points that differenciates the Roost from other laptop stands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elevates laptop screen higher&lt;/li&gt;
&lt;li&gt;Stable and strong in the ways it needs to be while remaining light and portable&lt;/li&gt;
&lt;li&gt;Lifetime warranty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it was unboxed, I could easily see myself packing and carrying it around. As I was holding it, the way to open it up wasn&amp;rsquo;t immediately apparent. Had to look at the instructions to figure out how to use this thing. Opening and closing it was one smooth sliding motion, holding the rubber feet. The laptop fits into the hooks and rests on the frame. It is very stable and does not wobble. The hooks grip the laptop well enough so that even if you tip the whole thing over, your laptop will not slide off the stand.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve been using the Roost laptop stand everyday now and I can&amp;rsquo;t recommend this enough. Elevating my laptop lets me maintain a good posture, removing strains from my neck, shoulders and back. It is also meant to work with  an external keyboard and mouse/trackpad. Although this setup is more than just a laptop, it is justifiable and is still extremely portable. If I&amp;rsquo;m bringing my laptop, the Roost together with a keyboard and trackpad comes with me too.&lt;/p&gt;

&lt;p&gt;There are many different types of laptop stands out in the market. As I travel frequently, this one suits my needs more than the others and I&amp;rsquo;m happy to share a great product with you. Learn more from &lt;a href="https://www.therooststand.com/"&gt;https://www.therooststand.com/&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>GitLab</title>
    <link rel="alternate" href="https://stnly.com/gitlab/"/>
    <id>https://stnly.com/gitlab/</id>
    <published>2016-01-09T08:00:00+08:00</published>
    <updated>2016-11-15T07:42:41+08:00</updated>
    <author>
      <name>Stanley Tan</name>
    </author>
    <content type="html">&lt;p&gt;Started moving the repositories that are in production from Bitbucket to GitLab over the weekend. Some reasons were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot search for code in Bitbucket repositories&lt;/li&gt;
&lt;li&gt;Gitlab has a CI service&lt;/li&gt;
&lt;li&gt;Gitlab is open source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After moving to GitLab, I took some time to set up an automated build, test and deploy cycle with GitLab CI for this website.&lt;/p&gt;

&lt;p&gt;Pretty impressed with the progress the team made over the years.&lt;/p&gt;
</content>
  </entry>
</feed>
