<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SATO, Yoshiyuki</title>
    <description>The latest articles on DEV Community by SATO, Yoshiyuki (@yoshi389111).</description>
    <link>https://dev.to/yoshi389111</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1069358%2F6106d03e-4f45-4e1b-bd6c-531810e7a491.png</url>
      <title>DEV Community: SATO, Yoshiyuki</title>
      <link>https://dev.to/yoshi389111</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yoshi389111"/>
    <language>en</language>
    <item>
      <title>Passwordless encryption with public key for GitHub</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Mon, 15 May 2023 00:57:28 +0000</pubDate>
      <link>https://dev.to/yoshi389111/passwordless-encryption-with-public-key-for-github-kb6</link>
      <guid>https://dev.to/yoshi389111/passwordless-encryption-with-public-key-for-github-kb6</guid>
      <description>&lt;p&gt;Public keys registered for authentication on GitHub and GitLab can be obtained by anyone. I made a command that can encrypt/decrypt files using that public key and own private key.&lt;/p&gt;

&lt;p&gt;This command can handle encrypted files without a password. Of course it is necessary if a passphrase is registered with the private key. However, there is no need to pass the password from the sender to the recipient.&lt;/p&gt;

&lt;p&gt;I named the command &lt;code&gt;git-caesar&lt;/code&gt;. Don't worry, I don't use the &lt;a href="https://en.wikipedia.org/wiki/Caesar_cipher" rel="noopener noreferrer"&gt;Caesar cipher&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's a new command, so there may be bugs.&lt;br&gt;
I'm not familiar with encryption technology, so I'm looking forward to hearing from people who know more.&lt;/p&gt;

&lt;p&gt;This command is heavily influenced by &lt;a href="https://github.com/Qithub-BOT/QiiCipher" rel="noopener noreferrer"&gt;QiiCipher&lt;/a&gt;.&lt;br&gt;
QiiCipher is also a shell script-based tool that encrypts/decrypts small files using RSA public keys for GitHub.&lt;br&gt;
QiiCipher is intended to be implemented with the minimum requirements of standard shell functions + OpenSSL/OpenSSH, while this command is implemented in the GO language to make it easier to handle.&lt;/p&gt;
&lt;h2&gt;
  
  
  Public key for GitHub and GitLab authentication
&lt;/h2&gt;

&lt;p&gt;I think it's common to register a public key for ssh in GitHub or GitLab for authentication during &lt;code&gt;git push&lt;/code&gt;.&lt;br&gt;
Anyone can obtain this registered public key.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub public key URL: &lt;code&gt;https://github.com/USER_NAME.keys&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;GitLab public key URL: &lt;code&gt;https://gitlab.com/USER_NAME.keys&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These public keys are primarily for signing, but some algorithms can also be used for encryption.&lt;br&gt;
Using this public key, passwordless encryption/decryption is realized.&lt;br&gt;
Public key encryption algorithms support RSA (key length of 1024 bits or more), ECDSA, and ED25519.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RSA (key length of 1024 bits or more)

&lt;ul&gt;
&lt;li&gt;public key prefix: &lt;code&gt;ssh-rsa&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ECDSA

&lt;ul&gt;
&lt;li&gt;P256 -- public key prefix: &lt;code&gt;ecdsa-sha2-nistp256&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;P384 -- public key prefix: &lt;code&gt;ecdsa-sha2-nistp384&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;P521 -- public key prefix: &lt;code&gt;ecdsa-sha2-nistp521&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ED25519 -- public key prefix: &lt;code&gt;ssh-ed25519&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others, namely DSA, ECDSA-SK and ED25519-SK for secret keys, and RSA with key length less than 1024 bits are not supported.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DSA -- Excluded from GitHub/GitLab due to deprecation and lack of research on how to implement it.

&lt;ul&gt;
&lt;li&gt;public key prefix: &lt;code&gt;ssh-dss&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ECDSA-SK, ED25519-SK -- As far as I have researched, I have determined that this is not possible. At least, it cannot be achieved simply by using a library.

&lt;ul&gt;
&lt;li&gt;public key prefix: &lt;code&gt;sk-ecdsa-sha2-nistp256@openssh.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;public key prefix: &lt;code&gt;sk-ssh-ed25519@openssh.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RSA (key length less than 1024 bits) -- determined to be a security problem. Also, since the key length is short, there are restrictions on key encryption.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Message body encryption
&lt;/h2&gt;

&lt;p&gt;Even when public-key cryptography is used, it is common to encrypt the body of the message with symmetric-key cryptography.&lt;br&gt;
This command uses symmetric key encryption method AES in AES-256-CBC mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/aes"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/cipher"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rand"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plaintext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// pad the message with PKCS#7&lt;/span&gt;
    &lt;span class="n"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;
    &lt;span class="n"&gt;padtext&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Repeat&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;padtext&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;iv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;encMsg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c"&gt;// generate initialization vector (IV)&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// encrypt message (AES-CBC)&lt;/span&gt;
    &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCipher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cbc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCBCEncrypter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cbc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CryptBlocks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padtext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// extract the initial vector (IV)&lt;/span&gt;
    &lt;span class="n"&gt;iv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;encMsg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlockSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c"&gt;// create an decrypter in CBC mode&lt;/span&gt;
    &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCipher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cbc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCBCDecrypter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// decrypt ciphertext&lt;/span&gt;
    &lt;span class="n"&gt;msgLen&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encMsg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;decMsg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msgLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cbc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CryptBlocks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encMsg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Unpad the message with PKCS#7&lt;/span&gt;
    &lt;span class="n"&gt;plaintext&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;decMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;msgLen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;msgLen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, prepare a shared key (32 bytes = 256 bits) by some method, such as random numbers or key exchange.&lt;br&gt;
Encrypt with AES-256-CBC using that shared key.&lt;br&gt;
A random number called an initialization vector (IV) is required for encryption.&lt;br&gt;
An IV is like a salt when hashing a password, so that even if the same data is encrypted, the ciphertext will be different. This is fine to publish.&lt;br&gt;
This IV must be passed to the recipient, so I insert it at the beginning of the ciphertext.&lt;br&gt;
When receiving, the first block is extracted as IV and then decoded.&lt;/p&gt;

&lt;p&gt;Also, AES-256-CBC requires padding that matches the block length.&lt;br&gt;
There are several methods of padding, but this time we use the PKCS#7 method.&lt;/p&gt;

&lt;p&gt;The ciphertext can be passed as it is, but the important point is how to share the shared key used for encryption with the other party.&lt;/p&gt;
&lt;h2&gt;
  
  
  For RSA public keys
&lt;/h2&gt;

&lt;p&gt;RSA public keys are limited to small enough data, but can also be used for encryption.&lt;br&gt;
However, primitive encryption methods are difficult for unskilled humans to master (for example, it is easy to make mistakes like using block ciphers in ECB cipher mode). So I used RSA-OAEP, a cipher suite using RSA.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rand"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rsa"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha256"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plaintext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncryptOAEP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DecryptOAEP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SignPKCS1v15&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VerifyPKCS1v15&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result of testing, if the RSA key length is about 800 bits, it seems that a 32-byte key can be encrypted.&lt;br&gt;
Since the key length supported this time is 1024 bits or more, a 32-byte key can be encrypted without problems.&lt;/p&gt;

&lt;p&gt;The shared key for AES-256-CBC is encrypted using the recipient's RSA public key and sent to the other party, who can then decrypt it with their own RSA private key.&lt;/p&gt;
&lt;h2&gt;
  
  
  For ECDSA public keys
&lt;/h2&gt;

&lt;p&gt;ECDSA is an algorithm for signing. Therefore, it cannot be used directly for encryption/decryption.&lt;br&gt;
Related to ECDSA is the ECDH key exchange algorithm, and ECDSA keys can be used almost as is for ECDH.&lt;br&gt;
And if you use key exchange, the sender uses "sender's private key" and "recipient's public key", and the receiver uses "recipient's private key" and "sender's public key" You can get the same key by exchanging the key.&lt;/p&gt;

&lt;p&gt;When using this exchanged key to encrypt/decrypt with a symmetric key encryption system such as AES, there is no need to pass the key itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ecdsa"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rand"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha256"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/asn1"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/yoshi389111/git-caesar/caesar/aes"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peersPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;curve&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;peersPubKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Curve&lt;/span&gt;

    &lt;span class="c"&gt;// generate temporary private key&lt;/span&gt;
    &lt;span class="n"&gt;tempPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// key exchange&lt;/span&gt;
    &lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;curve&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScalarMult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peersPubKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;peersPubKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tempPrvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;sharedKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// encrypt AES-256-CBC&lt;/span&gt;
    &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tempPrvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;peersPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;curve&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Curve&lt;/span&gt;

    &lt;span class="c"&gt;// key exchange&lt;/span&gt;
    &lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;curve&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScalarMult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peersPubKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;peersPubKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;sharedKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// decrypt AES-256-CBC&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;sigParam&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;asn1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sigParam&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sigParam&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;asn1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: As will be described later, the key pair for the sender is generated each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  For ED25519 public keys
&lt;/h2&gt;

&lt;p&gt;ED25519 is also an algorithm for signing. Therefore, it cannot be used for encryption/decryption as well.&lt;br&gt;
Also related to ED25519 is the X25519 key exchange algorithm.&lt;br&gt;
Calculations based on the ED25519 key yield the X25519 key.&lt;br&gt;
However, it is not possible to make an ED25519 key from a reversed X25519 key due to lossy transformation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ecdh"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ed25519"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha512"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;toX2519PrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edPrvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha512&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum512&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edPrvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X25519&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewPrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// p = 2^255 - 19&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;toX25519PublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// convert to big-endian&lt;/span&gt;
    &lt;span class="n"&gt;bigEndianY&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;edPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// turn off the first bit&lt;/span&gt;
    &lt;span class="n"&gt;bigEndianY&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b0111_1111&lt;/span&gt;

    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bigEndianY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;numer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c"&gt;// (1 + y)&lt;/span&gt;
    &lt;span class="n"&gt;denomInv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModInverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1 / (1 - y)&lt;/span&gt;
    &lt;span class="c"&gt;// u = (1 + y) / (1 - y)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;numer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;denomInv&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// convert to little-endian&lt;/span&gt;
    &lt;span class="n"&gt;littleEndianU&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FillBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;littleEndianU&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;littleEndianU&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;littleEndianU&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// create x25519 public key&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X25519&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;littleEndianU&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;toReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key exchange using X25519 is performed as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ecdh"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ed25519"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rand"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha256"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/yoshi389111/git-caesar/caesar/aes"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otherPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// generate temporary key pair&lt;/span&gt;
    &lt;span class="n"&gt;tempEdPubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tempEdPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// convert ed25519 public key to x25519 public key&lt;/span&gt;
    &lt;span class="n"&gt;xOtherPubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toX25519PublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otherPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// convert ed25519 prevate key to x25519 prevate key&lt;/span&gt;
    &lt;span class="n"&gt;xPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toX2519PrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tempEdPrvKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// key exchange&lt;/span&gt;
    &lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exchangeKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xOtherPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// encrypt AES-256-CBC&lt;/span&gt;
    &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tempEdPubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;otherPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// convert ed25519 public key to x25519 public key&lt;/span&gt;
    &lt;span class="n"&gt;xOtherPubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toX25519PublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otherPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// convert ed25519 prevate key to x25519 prevate key&lt;/span&gt;
    &lt;span class="n"&gt;xPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toX2519PrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// key exchange&lt;/span&gt;
    &lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exchangeKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xPrvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xOtherPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// decrypt AES-256-CBC&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;aes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;exchangeKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xPrvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xPubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ecdh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;xPrvKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ECDH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xPubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;sharedKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exchangedKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sharedKey&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;prvKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this exchanged key, encryption/decryption can be achieved in the same way as ECDSA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple public keys, different types of keys
&lt;/h2&gt;

&lt;p&gt;GitHub and GitLab can have multiple public keys.&lt;/p&gt;

&lt;p&gt;When working on multiple PCs/environments, using a single private key increases the possibility of leakage due to portability/copying.&lt;br&gt;
In order to avoid that, we will generate a key pair in each environment and register the public key of it on GitHub, etc.&lt;/p&gt;

&lt;p&gt;In this command, I wanted to make it possible for the receiver of the ciphertext to be able to decrypt it with any private key in such a case.&lt;/p&gt;

&lt;p&gt;Also, it is normal for the other party's key algorithm to be different from your own key algorithm.&lt;/p&gt;

&lt;p&gt;So I decided to encrypt it like this.&lt;br&gt;
First, the shared key that encrypts the message body is generated with random numbers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For RSA:

&lt;ol&gt;
&lt;li&gt;Encrypt the shared key using the recipient's RSA public key.&lt;/li&gt;
&lt;li&gt;Pass the encrypted shared key to the other party&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;For ECDSA, ED25519:

&lt;ol&gt;
&lt;li&gt;Generate a one-time key pair.&lt;/li&gt;
&lt;li&gt;Perform key exchange with the one-time private key and the recipient's public key.&lt;/li&gt;
&lt;li&gt;Encrypt the shared key with the exchanged key.&lt;/li&gt;
&lt;li&gt;Pass the encrypted shared key and the one-time public key to the other party&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The container containing the encrypted shared key and the one-time public key is called an envelope.&lt;/p&gt;

&lt;p&gt;The recipient selects the envelope that can be decrypted with own private key, restores the shared key, and decrypts the ciphertext.&lt;/p&gt;
&lt;h2&gt;
  
  
  Signature verification
&lt;/h2&gt;

&lt;p&gt;In addition to encryption/decryption, this command also signs the "encrypted message body" with the sender's private key.&lt;br&gt;
The recipient can check for spoofing and tampering by verifying the signature using her public key such as GitHub.&lt;/p&gt;

&lt;p&gt;Signature verification using GitHub etc. is optional. Decryption only is also possible without signature verification.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ciphertext file structure
&lt;/h2&gt;

&lt;p&gt;The ciphertext generated by this command is a ZIP file containing the following two files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;caesar.json&lt;/code&gt; - a json file containing the following items

&lt;ul&gt;
&lt;li&gt;signature data&lt;/li&gt;
&lt;li&gt;signer's public key&lt;/li&gt;
&lt;li&gt;version information&lt;/li&gt;
&lt;li&gt;list of envelopes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;caesar.cipher&lt;/code&gt; - encrypted message body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This ZIP file does not retain file name information before encryption. If necessary, the sender should inform the recipient of the file name separately.&lt;/li&gt;
&lt;li&gt;This ZIP file does not hold information about where the sender's public key is located (GitHub account name, URL, etc.).&lt;/li&gt;
&lt;li&gt;Encrypt only one file. If you encrypt multiple files at once, archive them in advance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Requires go 1.20 or higher.&lt;/p&gt;

&lt;p&gt;Execute the following commands to install and upgrade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go install github.com/yoshi389111/git-caesar@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To uninstall, run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go clean -i github.com/yoshi389111/git-caesar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usage:

  git-caesar [options]

Application Options:

  -h, --help                    print help and exit.
  -v, --version                 print version and exit.
  -u, --public=&amp;lt;target&amp;gt;         github account, url or file.
  -k, --private=&amp;lt;id_file&amp;gt;       ssh private key file.
  -i, --input=&amp;lt;input_file&amp;gt;      the path of the file to read. default: stdin
  -o, --output=&amp;lt;output_file&amp;gt;    the path of the file to write. default: stdout
  -d, --decrypt                 decryption mode.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; specifies the location of the peer's public key. Get from &lt;code&gt;https://github.com/USER_NAME.keys&lt;/code&gt; if the one specified looks like a GitHub username. If it starts with &lt;code&gt;http:&lt;/code&gt; or &lt;code&gt;https:&lt;/code&gt;, it will be fetched from the web. Otherwise, it will be determined as a file path. If you specify a file that looks like GitHub username, specify it with a path (e.g. &lt;code&gt;-u ./octacat&lt;/code&gt;). Required for encryption. For decryption, perform signature verification if specified.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-k&lt;/code&gt; Specify your private key. If not specified, it searches &lt;code&gt;~/.ssh/id_ecdsa&lt;/code&gt;, &lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt;, &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt; in order and uses the first one found.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-i&lt;/code&gt; Input file. Plaintext file to be encrypted when encrypting. When decrypting, please specify the ciphertext file to be decrypted. If no options are specified, it reads from standard input.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-o&lt;/code&gt; output file. Outputs to standard output if no option is specified.&lt;/li&gt;
&lt;li&gt;Specify &lt;code&gt;-d&lt;/code&gt; for decrypt mode. Encrypted mode if not specified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example of use
&lt;/h2&gt;

&lt;p&gt;Encrypt your file &lt;code&gt;secret.txt&lt;/code&gt; for GitHub user &lt;code&gt;octacat&lt;/code&gt; and save it as &lt;code&gt;sceret.zip&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-caesar -u octacat -i secret.txt -o secret.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the same situation, the private key uses &lt;code&gt;~/.ssh/id_secret&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-caesar -u octacat -i secret.txt -o secret.zip -k ~/.ssh/id_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decrypt GitLab user &lt;code&gt;tanuki&lt;/code&gt;'s file &lt;code&gt;secret.zip&lt;/code&gt; and save it as &lt;code&gt;sceret.txt&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-caesar -d -u https://gitlab.com/tanuki.keys -i secret.zip -o secret.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same situation, no signature verification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-caesar -d -i secret.zip -o secret.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;

&lt;p&gt;The GitHub repository is below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yoshi389111/git-caesar" rel="noopener noreferrer"&gt;https://github.com/yoshi389111/git-caesar&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>cryptography</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>Special icons for social accounts on GitHub</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Sat, 06 May 2023 12:12:27 +0000</pubDate>
      <link>https://dev.to/yoshi389111/special-icons-for-social-accounts-on-github-404k</link>
      <guid>https://dev.to/yoshi389111/special-icons-for-social-accounts-on-github-404k</guid>
      <description>&lt;p&gt;You can have up to 4 social account links on your GitHub profile.&lt;/p&gt;

&lt;p&gt;Follow the steps below for the settings.&lt;br&gt;
Your avatar on the top right of GitHub → settings → "Public profile" → "Social accounts"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.blog/changelog/2023-02-02-add-more-social-links-to-your-user-profile/" rel="noopener noreferrer"&gt;https://github.blog/changelog/2023-02-02-add-more-social-links-to-your-user-profile/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can now add up to 4 links to any social accounts to your user profile, with special support for popular platforms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It states that it has "special support for popular platforms".&lt;br&gt;
For example, if you register a Twitter URL, the chain icon will replace the Twitter icon.&lt;/p&gt;

&lt;p&gt;Specifically, I checked what platforms are supported.&lt;br&gt;
The checking method is simply looking at the HTML source.&lt;/p&gt;

&lt;p&gt;If you have any of the following social accounts, I recommend registering them on GitHub (up to 4).&lt;/p&gt;

&lt;p&gt;As of 2023-05-06, 9 social accounts seem to be supported.&lt;/p&gt;

&lt;p&gt;Added on 2023-10-14: The npm account logo has been added and it seems to be compatible with 10 types of social accounts.&lt;/p&gt;

&lt;p&gt;Added on 2025-03-01: The bluesky account logo has been added.&lt;/p&gt;
&lt;h2&gt;
  
  
  X (twitter)
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?(?:twitter|x)\.com/([^/?]+)/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://twitter.com/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8io4xpxtpvoi15g2v45e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8io4xpxtpvoi15g2v45e.png" alt="X Image" width="479" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  facebook
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:[^.]+\.)?facebook\.com/(?:[^/?]+/?|profile\.php\?id=\d+)$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://facebook.com/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn59zkjx6vwh8fn5waut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn59zkjx6vwh8fn5waut.png" alt="Facebook Image" width="500" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  instagram
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(www\.)?instagram\.com/[^/?]+/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://instagram.com/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05ml0o6dw4531k1dz12m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05ml0o6dw4531k1dz12m.png" alt="Instagram Image" width="500" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  linkedin
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?linkedin\.com/(?:in|company)/[^/?]+/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://linkedin.com/in/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwln33o7swcj454kxaj6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwln33o7swcj454kxaj6.png" alt="Linkedin Image" width="499" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  reddit
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?reddit\.com/u(?:ser)?/([^/?]+)/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://reddit.com/u/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lvki4tcb3zucckg7sjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lvki4tcb3zucckg7sjr.png" alt="Reddit Image" width="500" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  twitch
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?twitch\.tv/[^/?]+/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://twitch.tv/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzcul4av7ns0ijquw1a0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzcul4av7ns0ijquw1a0f.png" alt="Twitch Image" width="498" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  youtube
&lt;/h2&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?youtube\.com/(user|c)/[^/?]+/?$
^https://(?:www\.)?youtube\.com/channel/[a-zA-Z0-9_-]{24}/?$
^https://(?:www\.)?youtube\.com/@[^/?]+/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://youtube.com/user/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1pz1f2q3l80w2t01t03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1pz1f2q3l80w2t01t03.png" alt="Youtube Image" width="499" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  mastodon
&lt;/h2&gt;

&lt;p&gt;I don't know the specific pattern, but Mastodon seems to be supported.&lt;/p&gt;

&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mastodon.social/@test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0mp2qb1hbmagmaru36d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0mp2qb1hbmagmaru36d.png" alt="Mastodon Image" width="495" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  hometown
&lt;/h2&gt;

&lt;p&gt;hometown seems to be a SNS that forked mastodon.&lt;/p&gt;

&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://rage.love/@test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a test URL from the server list on the following site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hometown-fork/hometown/wiki/Hometown-servers" rel="noopener noreferrer"&gt;https://github.com/hometown-fork/hometown/wiki/Hometown-servers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The icon looks the same as the mastodon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk91dx61umtf99shzamlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk91dx61umtf99shzamlz.png" alt="Hometown Image" width="499" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  npm
&lt;/h2&gt;

&lt;p&gt;Added on 2023-10-14.&lt;/p&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://(?:www\.)?npmjs\.com/~([^/?]+)/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://npmjs.com/~test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fmrejgkjjhtz3qwiseg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fmrejgkjjhtz3qwiseg.png" alt="Npm Image" width="450" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  bluesky
&lt;/h2&gt;

&lt;p&gt;Added on 2025-03-01.&lt;/p&gt;

&lt;p&gt;Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^https://bsky\.app/profile/([^@/]+)/?$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://bsky.app/profile/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61t6g0wb2yveizg39ieo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61t6g0wb2yveizg39ieo.png" alt="Bluesky Image" width="432" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>Check number of CPUs</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Sat, 06 May 2023 00:22:39 +0000</pubDate>
      <link>https://dev.to/yoshi389111/check-number-of-cpus-457j</link>
      <guid>https://dev.to/yoshi389111/check-number-of-cpus-457j</guid>
      <description>&lt;h2&gt;
  
  
  Check number of CPUs in Linux
&lt;/h2&gt;

&lt;p&gt;I wanted to know the number of CPUs in my Linux environment. The following Japanese version of the page was helpful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://access.redhat.com/ja/solutions/2159401"&gt;物理 CPU、CPU コア、および論理 CPU の数を確認する&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The corresponding English page looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://access.redhat.com/solutions/224883"&gt;How to find the number of physical cpus, cpu cores, and logical cpus&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Number of physical CPUs
&lt;/h3&gt;

&lt;p&gt;Some machines have multiple physical CPUs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fgrep 'physical id' /proc/cpuinfo | sort -u | wc -l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Number of CPU cores
&lt;/h3&gt;

&lt;p&gt;Some modern CPUs have multiple cores on a single physical CPU.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fgrep 'cpu cores' /proc/cpuinfo | sort -u | sed 's/.*: //'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Number of logical processors
&lt;/h3&gt;

&lt;p&gt;Modern CPUs can do multiple things with a single core using features like hyper-threading.&lt;/p&gt;

&lt;p&gt;Therefore, the number of logical processors can be greater than the number of physical CPUs times the number of cores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fgrep 'processor' /proc/cpuinfo | wc -l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Simple shell script
&lt;/h3&gt;

&lt;p&gt;Assuming all physical CPUs have the same number of cores, and hyper-threading as well, what would it look like?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;P_CPU&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; fgrep &lt;span class="s1"&gt;'physical id'&lt;/span&gt; /proc/cpuinfo | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;CORES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; fgrep &lt;span class="s1"&gt;'cpu cores'&lt;/span&gt; /proc/cpuinfo | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/.*: //'&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;L_PRC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; fgrep &lt;span class="s1"&gt;'processor'&lt;/span&gt; /proc/cpuinfo | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;H_TRD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; L_PRC &lt;span class="o"&gt;/&lt;/span&gt;  P_CPU &lt;span class="o"&gt;/&lt;/span&gt; CORES &lt;span class="k"&gt;))&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;L_PRC&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; processer"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;L_PRC&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;" = &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;P_CPU&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; socket"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;P_CPU&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;" x &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CORES&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; core"&lt;/span&gt;   &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CORES&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;" x &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;H_TRD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; thread"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;H_TRD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 1 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cpucore.sh
8 processers = 1 socket x 4 cores x 2 threads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  lscpu command
&lt;/h3&gt;

&lt;p&gt;As I learned later, there seems to be a command called &lt;code&gt;lscpu&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lscpu
Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   39 bits physical, 48 bits virtual
CPU(s):                          8
On-line CPU(s) list:             0-7
Thread(s) per core:              2
Core(s) per socket:              4
Socket(s):                       1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           142
Model name:                      Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
Stepping:                        10
CPU MHz:                         1799.998
BogoMIPS:                        3599.99
Virtualization:                  VT-x
Hypervisor vendor:               Microsoft
Virtualization type:             full
L1d cache:                       128 KiB
L1i cache:                       128 KiB
L2 cache:                        1 MiB
L3 cache:                        6 MiB
...Omitted below
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think the following will be the same information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread(s) per core: 2&lt;/li&gt;
&lt;li&gt;Core(s) per socket: 4&lt;/li&gt;
&lt;li&gt;Socket(s): 1&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check number of CPUs in Windows
&lt;/h2&gt;

&lt;p&gt;On Windows, it seems that you can check the number of CPUs in the same way as above with the following API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor"&gt;Win32_Processor class&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems that C ++ and C #, as well as PowerShell and VB can be acquired.&lt;/p&gt;

&lt;p&gt;For the time being, in the case of VBS, I think that it will be as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vb"&gt;&lt;code&gt;&lt;span class="k"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Explicit&lt;/span&gt;

&lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="nv"&gt;locator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultSet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;
&lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="nv"&gt;nSocket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nCore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalThread&lt;/span&gt;
&lt;span class="k"&gt;Dim&lt;/span&gt; &lt;span class="nv"&gt;msg&lt;/span&gt;

&lt;span class="n"&gt;nSocket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;totalThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;Set&lt;/span&gt; &lt;span class="n"&gt;locator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WbemScripting.SWbemLocator"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;Set&lt;/span&gt; &lt;span class="n"&gt;resultSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;locator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExecQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM Win32_Processor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nSocket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;For&lt;/span&gt; &lt;span class="k"&gt;Each&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt; &lt;span class="ow"&gt;In&lt;/span&gt; &lt;span class="n"&gt;resultSet&lt;/span&gt;
  &lt;span class="n"&gt;nCore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumberOfCores&lt;/span&gt;
  &lt;span class="n"&gt;nThread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumberOfLogicalProcessors&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumberOfCores&lt;/span&gt;
  &lt;span class="n"&gt;totalThread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalThread&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumberOfLogicalProcessors&lt;/span&gt;
&lt;span class="k"&gt;Next&lt;/span&gt;

&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalThread&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" processer"&lt;/span&gt;
&lt;span class="k"&gt;If&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;totalThread&lt;/span&gt; &lt;span class="k"&gt;Then&lt;/span&gt;
  &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"s"&lt;/span&gt;
&lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;If&lt;/span&gt;

&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" = "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nSocket&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" socket"&lt;/span&gt;
&lt;span class="k"&gt;If&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nSocket&lt;/span&gt; &lt;span class="k"&gt;Then&lt;/span&gt;
  &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"s"&lt;/span&gt;
&lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;If&lt;/span&gt;

&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" x "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nCore&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" core"&lt;/span&gt;
&lt;span class="k"&gt;If&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nCore&lt;/span&gt; &lt;span class="k"&gt;Then&lt;/span&gt;
  &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"s"&lt;/span&gt;
&lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;If&lt;/span&gt;

&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" x "&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;nThread&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;" thread"&lt;/span&gt;
&lt;span class="k"&gt;If&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nThread&lt;/span&gt; &lt;span class="k"&gt;Then&lt;/span&gt;
  &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"s"&lt;/span&gt;
&lt;span class="k"&gt;End&lt;/span&gt; &lt;span class="k"&gt;If&lt;/span&gt;

&lt;span class="n"&gt;WScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Echo&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>shell</category>
      <category>windows</category>
    </item>
    <item>
      <title>Show ERRNO and Value</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Fri, 05 May 2023 05:55:17 +0000</pubDate>
      <link>https://dev.to/yoshi389111/show-errno-and-value-48gl</link>
      <guid>https://dev.to/yoshi389111/show-errno-and-value-48gl</guid>
      <description>&lt;p&gt;I think there are times when I want to know the value of ERRNO when I build a program, or when I want to know the error message corresponding to the value, such as an error message of some command.&lt;br&gt;
At times like that, I check with a simple shell script I made N years ago.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't think about difficult things such as whether it works in any environment or whether all errno can be checked (just think about it when it doesn't work).&lt;/li&gt;
&lt;li&gt;For the time being, I moved in an environment where gcc is installed in Linux.&lt;/li&gt;
&lt;li&gt;It just grep the include file for C language.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;errno.sh&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The created &lt;code&gt;errno.sh&lt;/code&gt; script is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-ne&lt;/span&gt; 1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-h"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"--help"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; { ERROR_NUMBER | ERROR_NAME }"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class="nb"&gt;exit &lt;/span&gt;1

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ ^E[A-Z0-9]+&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ ^[1-9][0-9]&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"illegal argument."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class="nb"&gt;exit &lt;/span&gt;1

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; find /usr/include &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'errno*.h'&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; |
  xargs &lt;span class="nt"&gt;-0&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Eh&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*define&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+E[A-Z0-9]+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*define&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+[1-9][0-9]*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s*define&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+E[A-Z0-9]+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt;
&lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"errno not found(&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;)."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some examples are shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ errno.sh
Usage: errno.sh { ERROR_NUMBER | ERROR_NAME }
$ errno.sh EIO
#define EIO              5      /* I/O error */
$ errno.sh 125
#define ECANCELED       125     /* Operation Canceled */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  note
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ERRNO range
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ for N in $(seq 1 140) ; do errno.sh $N ; done
#define EPERM            1      /* Operation not permitted */
#define ENOENT           2      /* No such file or directory */
#define ESRCH            3      /* No such process */
#define EINTR            4      /* Interrupted system call */
#define EIO              5      /* I/O error */
#define ENXIO            6      /* No such device or address */
#define E2BIG            7      /* Argument list too long */
#define ENOEXEC          8      /* Exec format error */
#define EBADF            9      /* Bad file number */
#define ECHILD          10      /* No child processes */
#define EAGAIN          11      /* Try again */
#define ENOMEM          12      /* Out of memory */
#define EACCES          13      /* Permission denied */
#define EFAULT          14      /* Bad address */
#define ENOTBLK         15      /* Block device required */
#define EBUSY           16      /* Device or resource busy */
#define EEXIST          17      /* File exists */
#define EXDEV           18      /* Cross-device link */
#define ENODEV          19      /* No such device */
#define ENOTDIR         20      /* Not a directory */
#define EISDIR          21      /* Is a directory */
#define EINVAL          22      /* Invalid argument */
#define ENFILE          23      /* File table overflow */
#define EMFILE          24      /* Too many open files */
#define ENOTTY          25      /* Not a typewriter */
#define ETXTBSY         26      /* Text file busy */
#define EFBIG           27      /* File too large */
#define ENOSPC          28      /* No space left on device */
#define ESPIPE          29      /* Illegal seek */
#define EROFS           30      /* Read-only file system */
#define EMLINK          31      /* Too many links */
#define EPIPE           32      /* Broken pipe */
#define EDOM            33      /* Math argument out of domain of func */
# define EDOM   33      /* Math argument out of domain of function.  */
#define ERANGE          34      /* Math result not representable */
# define ERANGE 34      /* Math result not representable.  */
#define EDEADLK         35      /* Resource deadlock would occur */
#define ENAMETOOLONG    36      /* File name too long */
#define ENOLCK          37      /* No record locks available */
#define ENOSYS          38      /* Function not implemented */
#define ENOTEMPTY       39      /* Directory not empty */
#define ELOOP           40      /* Too many symbolic links encountered */
errno not found(41).
#define ENOMSG          42      /* No message of desired type */
#define EIDRM           43      /* Identifier removed */
#define ECHRNG          44      /* Channel number out of range */
#define EL2NSYNC        45      /* Level 2 not synchronized */
#define EL3HLT          46      /* Level 3 halted */
#define EL3RST          47      /* Level 3 reset */
#define ELNRNG          48      /* Link number out of range */
#define EUNATCH         49      /* Protocol driver not attached */
#define ENOCSI          50      /* No CSI structure available */
#define EL2HLT          51      /* Level 2 halted */
#define EBADE           52      /* Invalid exchange */
#define EBADR           53      /* Invalid request descriptor */
#define EXFULL          54      /* Exchange full */
#define ENOANO          55      /* No anode */
#define EBADRQC         56      /* Invalid request code */
#define EBADSLT         57      /* Invalid slot */
errno not found(58).
#define EBFONT          59      /* Bad font file format */
#define ENOSTR          60      /* Device not a stream */
#define ENODATA         61      /* No data available */
#define ETIME           62      /* Timer expired */
#define ENOSR           63      /* Out of streams resources */
#define ENONET          64      /* Machine is not on the network */
#define ENOPKG          65      /* Package not installed */
#define EREMOTE         66      /* Object is remote */
#define ENOLINK         67      /* Link has been severed */
#define EADV            68      /* Advertise error */
#define ESRMNT          69      /* Srmount error */
#define ECOMM           70      /* Communication error on send */
#define EPROTO          71      /* Protocol error */
#define EMULTIHOP       72      /* Multihop attempted */
#define EDOTDOT         73      /* RFS specific error */
#define EBADMSG         74      /* Not a data message */
#define EOVERFLOW       75      /* Value too large for defined data type */
#define ENOTUNIQ        76      /* Name not unique on network */
#define EBADFD          77      /* File descriptor in bad state */
#define EREMCHG         78      /* Remote address changed */
#define ELIBACC         79      /* Can not access a needed shared library */
#define ELIBBAD         80      /* Accessing a corrupted shared library */
#define ELIBSCN         81      /* .lib section in a.out corrupted */
#define ELIBMAX         82      /* Attempting to link in too many shared libraries */
#define ELIBEXEC        83      /* Cannot exec a shared library directly */
#define EILSEQ          84      /* Illegal byte sequence */
# define EILSEQ 84      /* Illegal byte sequence.  */
#define ERESTART        85      /* Interrupted system call should be restarted */
#define ESTRPIPE        86      /* Streams pipe error */
#define EUSERS          87      /* Too many users */
#define ENOTSOCK        88      /* Socket operation on non-socket */
#define EDESTADDRREQ    89      /* Destination address required */
#define EMSGSIZE        90      /* Message too long */
#define EPROTOTYPE      91      /* Protocol wrong type for socket */
#define ENOPROTOOPT     92      /* Protocol not available */
#define EPROTONOSUPPORT 93      /* Protocol not supported */
#define ESOCKTNOSUPPORT 94      /* Socket type not supported */
#define EOPNOTSUPP      95      /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT    96      /* Protocol family not supported */
#define EAFNOSUPPORT    97      /* Address family not supported by protocol */
#define EADDRINUSE      98      /* Address already in use */
#define EADDRNOTAVAIL   99      /* Cannot assign requested address */
#define ENETDOWN        100     /* Network is down */
#define ENETUNREACH     101     /* Network is unreachable */
#define ENETRESET       102     /* Network dropped connection because of reset */
#define ECONNABORTED    103     /* Software caused connection abort */
#define ECONNRESET      104     /* Connection reset by peer */
#define ENOBUFS         105     /* No buffer space available */
#define EISCONN         106     /* Transport endpoint is already connected */
#define ENOTCONN        107     /* Transport endpoint is not connected */
#define ESHUTDOWN       108     /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS    109     /* Too many references: cannot splice */
#define ETIMEDOUT       110     /* Connection timed out */
#define ECONNREFUSED    111     /* Connection refused */
#define EHOSTDOWN       112     /* Host is down */
#define EHOSTUNREACH    113     /* No route to host */
#define EALREADY        114     /* Operation already in progress */
#define EINPROGRESS     115     /* Operation now in progress */
#define ESTALE          116     /* Stale file handle */
#define EUCLEAN         117     /* Structure needs cleaning */
#define ENOTNAM         118     /* Not a XENIX named type file */
#define ENAVAIL         119     /* No XENIX semaphores available */
#define EISNAM          120     /* Is a named type file */
#define EREMOTEIO       121     /* Remote I/O error */
#define EDQUOT          122     /* Quota exceeded */
#define ENOMEDIUM       123     /* No medium found */
#define EMEDIUMTYPE     124     /* Wrong medium type */
#define ECANCELED       125     /* Operation Canceled */
#  define ECANCELED     125
#define ENOKEY          126     /* Required key not available */
#define EKEYEXPIRED     127     /* Key has expired */
#define EKEYREVOKED     128     /* Key has been revoked */
#define EKEYREJECTED    129     /* Key was rejected by service */
#define EOWNERDEAD      130     /* Owner died */
#  define EOWNERDEAD            130
#define ENOTRECOVERABLE 131     /* State not recoverable */
#  define ENOTRECOVERABLE       131
#define ERFKILL         132     /* Operation not possible due to RF-kill */
#  define ERFKILL               132
#define EHWPOISON       133     /* Memory page has hardware error */
#  define EHWPOISON             133
errno not found(134).
errno not found(135).
errno not found(136).
errno not found(137).
errno not found(138).
errno not found(139).
errno not found(140).
$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ERRNO with multiple names
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ errno.sh EDEADLK
#define EDEADLK         35      /* Resource deadlock would occur */
#define EDEADLOCK       EDEADLK
$ errno.sh EAGAIN
#define EAGAIN          11      /* Try again */
#define EWOULDBLOCK     EAGAIN  /* Operation would block */
$ errno.sh EOPNOTSUPP
#define EOPNOTSUPP      95      /* Operation not supported on transport endpoint */
# define ENOTSUP EOPNOTSUPP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>shell</category>
      <category>bash</category>
    </item>
    <item>
      <title>I made a VSCode extension: "Visible Whitespace"</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Sat, 29 Apr 2023 20:57:00 +0000</pubDate>
      <link>https://dev.to/yoshi389111/i-made-a-vscode-extension-visible-whitespace-l7j</link>
      <guid>https://dev.to/yoshi389111/i-made-a-vscode-extension-visible-whitespace-l7j</guid>
      <description>&lt;p&gt;Last month, I made &lt;a href="https://dev.to/yoshi389111/i-made-a-vscode-extension-markdown-table-rainbow-4l27"&gt;a VSCode extension&lt;/a&gt; and learned about VSCode Decorators for it.&lt;br&gt;
At that time, I wanted to create another VSCode extension even if I used a certain function of Decorator.&lt;/p&gt;

&lt;p&gt;And what I made is "Visible Whitespace".&lt;br&gt;
This is an extension that makes whitespace visible.&lt;/p&gt;

&lt;p&gt;A similar extension already exists.&lt;br&gt;
However, in order to output the results of learning, I decided to make one myself.&lt;/p&gt;

&lt;p&gt;This extension is published on the marketplace.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;marketplace: &lt;a href="https://marketplace.visualstudio.com/items?itemName=yoshi389111.visible-whitespace"&gt;Visible Whitespace&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The source code is on GitHub.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yoshi389111"&gt;
        yoshi389111
      &lt;/a&gt; / &lt;a href="https://github.com/yoshi389111/visible-whitespace"&gt;
        visible-whitespace
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A VS Code extension that makes whitespace visible.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Visible Whitespace&lt;/h1&gt;
&lt;p&gt;An extension that makes whitespace visible.&lt;/p&gt;
&lt;h2&gt;
Features&lt;/h2&gt;
&lt;p&gt;This extension visually displays the following whitespace characters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;H-TAB (U+0009) - Disabled by default.&lt;/li&gt;
&lt;li&gt;LF (U+000A) or CRLF (U+000D + U+000A)&lt;/li&gt;
&lt;li&gt;Space (U+0020) - Disabled by default.&lt;/li&gt;
&lt;li&gt;No-Break Space (U+00A0)&lt;/li&gt;
&lt;li&gt;Ideographic Space (U+3000)&lt;/li&gt;
&lt;li&gt;other whitespace (U+180E, U+2000-U+200A, U+202F, U+205F, U+2800)&lt;/li&gt;
&lt;li&gt;EOF&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/yoshi389111/visible-whitespaceassets/screenshot.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xJkXseuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/yoshi389111/visible-whitespaceassets/screenshot.png" alt="screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Extension Settings&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.enabledLanguageIds&lt;/code&gt;: A list of languageIds for which this extension should be enabled. If empty, it will be enabled for all languageIds. e.g. &lt;code&gt;[ "plaintext", "markdown" ]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.updateDelay&lt;/code&gt;: Delay time in milliseconds before updating. Smaller values will color faster, but will increase processing cost.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.overlayColor&lt;/code&gt;: Specify the color of the overlay text. eg. &lt;code&gt;#RRGGBB&lt;/code&gt;, &lt;code&gt;rgb(R,G,B)&lt;/code&gt; or &lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.htab.enable&lt;/code&gt;: Enables making horizontal tabs visible. (default: false)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.htab.text&lt;/code&gt;: Text to overlay on horizontal tabs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.enable&lt;/code&gt;: Enables making new line visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.lf&lt;/code&gt;: Text of LF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.crLf&lt;/code&gt;: Text of CRLF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.color&lt;/code&gt;: Color…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yoshi389111/visible-whitespace"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How to install
&lt;/h2&gt;

&lt;p&gt;Download it from the marketplace or search for &lt;code&gt;Visible Whitespace&lt;/code&gt; in VSCode Extensions and install it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;This extension visually displays the following whitespace characters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;H-TAB (U+0009) - Disabled by default.&lt;/li&gt;
&lt;li&gt;LF (U+000A) or CRLF (U+000D + U+000A)&lt;/li&gt;
&lt;li&gt;Space (U+0020) - Disabled by default.&lt;/li&gt;
&lt;li&gt;No-Break Space (U+00A0)&lt;/li&gt;
&lt;li&gt;Ideographic Space (U+3000)&lt;/li&gt;
&lt;li&gt;other whitespace (U+180E, U+2000-U+200A, U+202F, U+205F, U+2800)&lt;/li&gt;
&lt;li&gt;EOF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QQZ4xAmU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/yoshi389111/visible-whitespace/raw/main/assets/screenshot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QQZ4xAmU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/yoshi389111/visible-whitespace/raw/main/assets/screenshot.png" alt="screenshot" width="540" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extension Settings
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.enabledLanguageIds&lt;/code&gt;: A list of languageIds for which this extension should be enabled. If empty, it will be enabled for all languageIds. e.g. &lt;code&gt;[ "plaintext", "markdown" ]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.updateDelay&lt;/code&gt;: Delay time in milliseconds before updating. Smaller values will color faster, but will increase processing cost.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.overlayColor&lt;/code&gt;: Specify the color of the overlay text. eg. &lt;code&gt;#RRGGBB&lt;/code&gt;, &lt;code&gt;rgb(R,G,B)&lt;/code&gt; or &lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.htab.enable&lt;/code&gt;: Enables making horizontal tabs visible. (default: false)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.htab.text&lt;/code&gt;: Text to overlay on horizontal tabs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.enable&lt;/code&gt;: Enables making new line visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.lf&lt;/code&gt;: Text of LF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.crLf&lt;/code&gt;: Text of CRLF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.newLine.color&lt;/code&gt;: Color of text that represents new line.  eg. &lt;code&gt;#RRGGBB&lt;/code&gt;, &lt;code&gt;rgb(R,G,B)&lt;/code&gt; or &lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.space.enable&lt;/code&gt;: Enables making spaces visible. (default: false)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.space.render&lt;/code&gt;: Controls how the editor should render spaces. (default: "all")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.space.text&lt;/code&gt;: Text to overlay on spaces.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.nbsp.enable&lt;/code&gt;: Enables making no-break spaces visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.nbsp.text&lt;/code&gt;: Text to overlay on no-break spaces.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.widespace.enable&lt;/code&gt;: Enables making wide-spaces visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.widespace.text&lt;/code&gt;: Text to overlay on wide-spaces.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.other.enable&lt;/code&gt;: Enables making other whitespaces visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.other.borderColor&lt;/code&gt;: Border color of other whitespace.  eg. &lt;code&gt;#RRGGBB&lt;/code&gt;, &lt;code&gt;rgb(R,G,B)&lt;/code&gt; or &lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.eof.enable&lt;/code&gt;: Enables making EOF visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.eof.text&lt;/code&gt;: Text of EOF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;visibleWhitespace.eof.color&lt;/code&gt;: Color of text that represents EOF.  eg. &lt;code&gt;#RRGGBB&lt;/code&gt;, &lt;code&gt;rgb(R,G,B)&lt;/code&gt; or &lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default for &lt;code&gt;visibleWhitespace.htab.enable&lt;/code&gt; and &lt;code&gt;visibleWhitespace.space.enable&lt;/code&gt; is disable because the standard &lt;code&gt;editor.renderWhitespace&lt;/code&gt; is used.&lt;/p&gt;

&lt;p&gt;If you want to use this extension instead of the standard &lt;code&gt;editor.renderWhitespace&lt;/code&gt;, set &lt;code&gt;"editor.renderWhitespace": "none"&lt;/code&gt; and set the above definition to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sites used as reference for creation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/api/references/vscode-api"&gt;official VSCode API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/vscode-extension-samples/tree/main/decorator-sample"&gt;Official sample extension (Decorator)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Miscellaneous Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  overlay characters
&lt;/h3&gt;

&lt;p&gt;I didn't understand it just by looking at the API specifications, but I learned that you can use character decorations to overlay characters.&lt;/p&gt;

&lt;p&gt;If you specify the content in &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;"0"&lt;/code&gt; in &lt;code&gt;width&lt;/code&gt;, it will be displayed overlapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;3000/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decorationType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTextEditorDecorationType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;rangeBehavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DecorationRangeBehavior&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClosedClosed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;contentText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;u2395&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(127,127,127)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This overlay feature made me want to make this extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interference with other extensions
&lt;/h3&gt;

&lt;p&gt;Originally, the newline code was displayed as a normal &lt;code&gt;before&lt;/code&gt;.&lt;br&gt;
In other words, you didn't set &lt;code&gt;widht&lt;/code&gt; to &lt;code&gt;"0"&lt;/code&gt;.&lt;br&gt;
However, when I used it in conjunction with some other extension, it behaved strangely.&lt;/p&gt;

&lt;p&gt;Specifically, with this extension only, the cursor does not move behind the before code of the new line code.&lt;br&gt;
However, when used with some extensions, the cursor was not positioned in front of the arrow of the new line code, and moved behind the arrow. .&lt;/p&gt;

&lt;p&gt;Therefore, I specified &lt;code&gt;width: "0"&lt;/code&gt; for the new line code and EOF just in case.&lt;/p&gt;

&lt;p&gt;I have not been able to investigate what specific extensions were hit.&lt;/p&gt;
&lt;h3&gt;
  
  
  APL symbols, etc.
&lt;/h3&gt;

&lt;p&gt;Currently, wide-spaces are displayed by overlapping squares by default.&lt;/p&gt;

&lt;p&gt;The overlayed square "⎕" (U+2395) is a character called "APL Functional Symbol Quad" in Unicode, and it seems to be a symbol for functions in the APL language.&lt;/p&gt;

&lt;p&gt;At first I was going to use "□" (U+25A1; "White Square").&lt;br&gt;
However, this character is designed to be wide in fonts such as Japanese, but is designed to be narrow (small because it is square) in fonts such as English.&lt;br&gt;
In &lt;a href="https://www.unicode.org/reports/tr11/"&gt;East Asian Width&lt;/a&gt;, this character is treated as A (ambiguous).&lt;br&gt;
That is, characters that may or may not be wide depending on the context in which they appear.&lt;br&gt;
Therefore, I thought that it might not be displayed well depending on the setting.&lt;br&gt;
So we use U+2395 above.&lt;br&gt;
It's a character added in Unicode 3.0, so I think it's already displayable in most environments.&lt;/p&gt;

&lt;p&gt;If there seems to be an environment where the APL symbol is not displayed well, please define to display it with a different character.&lt;/p&gt;

&lt;p&gt;Similarly, No-Break Space is also an APL symbol. If this is also not displayed well, please define so that it is displayed with some suitable character.&lt;/p&gt;

&lt;p&gt;If there are any other problems related to East Asian character widths, etc., please define them so that they are displayed with appropriate characters as well.&lt;/p&gt;
&lt;h3&gt;
  
  
  Text decoration border
&lt;/h3&gt;

&lt;p&gt;Above, "other whitespaces" are marked with a vermilion border.&lt;br&gt;
However, if these characters are consecutive, the border range will join.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;
&lt;h3&gt;
  
  
  Display of before/after elements remains temporarily
&lt;/h3&gt;

&lt;p&gt;When deleting the new line code, the arrow representing the new line code may remain for a moment.&lt;br&gt;
Then it disappears after the display update delay time.&lt;/p&gt;

&lt;p&gt;At that time, &lt;code&gt;width: "0"&lt;/code&gt; was not specified for the new line code.&lt;br&gt;
In that state, if you delete multiple lines at once, multiple arrows representing new line codes are displayed together for a moment immediately after deletion, and then disappear.&lt;/p&gt;

&lt;p&gt;In my environment, after setting the display width of the newline code to &lt;code&gt;width: "0"&lt;/code&gt;, it doesn't bother me much.&lt;br&gt;
If it bothers you, please turn off the new line code display.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mixed new line code
&lt;/h3&gt;

&lt;p&gt;Even if he opens a file with line endings mixed with LF and CRLF, VSCode seems to compensate for either when opening the file.&lt;br&gt;
So, I don't think there is basically a case where new line codes are mixed on one editor.&lt;/p&gt;
&lt;h3&gt;
  
  
  Defining activationEvents
&lt;/h3&gt;

&lt;p&gt;Initially, this extension did not narrow down the file type and set &lt;code&gt;"activationEvents": ["*"]&lt;/code&gt;, so when the extension was published (when the &lt;code&gt;vsce publish&lt;/code&gt; command was executed), a warning was issued every time. I was.&lt;/p&gt;

&lt;p&gt;I reread the &lt;a href="https://code.visualstudio.com/api/references/activation-events#onStartupFinished"&gt;documentation&lt;/a&gt; and found something called &lt;code&gt;onStartupFinished&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This activation event is emitted and interested extensions will be activated some time after VS Code starts up. This is similar to the &lt;code&gt;*&lt;/code&gt; activation event, but it will not slow down VS Code startup. Currently, this event is emitted after all the &lt;code&gt;*&lt;/code&gt; activated extensions have finished activating.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;*&lt;/code&gt; slows down the startup performance, but &lt;code&gt;onStartupFinished&lt;/code&gt; is called after the startup process is finished, so I decided that the performance problem would disappear.&lt;/p&gt;
&lt;h3&gt;
  
  
  With or without BOM
&lt;/h3&gt;

&lt;p&gt;For files with BOM, I wanted to place the BOM gutter icon on the first line.&lt;/p&gt;

&lt;p&gt;However, it seems that VSCode cannot acquire the character code and the presence or absence of her BOM, so I gave up.&lt;/p&gt;
&lt;h3&gt;
  
  
  EOF range specification
&lt;/h3&gt;

&lt;p&gt;The EOF range specifies a range of 0 characters after the last character of the document.&lt;br&gt;
Feeling like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eofPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;positionAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eofPosition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eofPosition&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such specifications were also possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  color specification format
&lt;/h3&gt;

&lt;p&gt;There are some items in &lt;code&gt;settings.json&lt;/code&gt; that let you specify colors.&lt;br&gt;
There is no color in VSCode's definition type, so I'm trying to have it defined as a &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If it is just &lt;code&gt;string&lt;/code&gt;, it will be in free format, so we specify a regular expression for &lt;code&gt;pattern&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt; to check the color specification format.&lt;/p&gt;

&lt;p&gt;Currently, the following three patterns are allowed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;#RRGGBB&lt;/code&gt; format. RR/GG/BB are two hexadecimal digits&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rgb(R,G,B)&lt;/code&gt; format. R/G/B ranges from 0 to 255. A cannot be specified&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rgba(R,G,B,A)&lt;/code&gt; format. R/G/B ranges from 0 to 255. A is from 0 to 1, and the decimal point format is also possible (in fact, &lt;code&gt;1.999&lt;/code&gt; etc. may also be specified)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No other formats are currently accepted.&lt;br&gt;
This is because only one regular expression is specified in the &lt;code&gt;pattern&lt;/code&gt; of &lt;code&gt;package.json&lt;/code&gt;, so it is difficult to perform complicated checks.&lt;/p&gt;

&lt;p&gt;Is it better to specify &lt;code&gt;#RGB&lt;/code&gt;, &lt;code&gt;#RRGGBBAA&lt;/code&gt; and &lt;code&gt;hsv()&lt;/code&gt;?&lt;br&gt;
Also, would it be better if &lt;code&gt;rgb()&lt;/code&gt; could specify the alpha channel as well?&lt;/p&gt;

&lt;h2&gt;
  
  
  Japanese version of this document
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Qiita: &lt;a href="https://qiita.com/yoshi389111/items/0ae999c73acb2887424b"&gt;全角スペース/改行/EOFとかを可視化するVSCode拡張機能を作ったよ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>vscode</category>
      <category>extension</category>
    </item>
    <item>
      <title>POng is Not pinG.</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Mon, 24 Apr 2023 14:06:28 +0000</pubDate>
      <link>https://dev.to/yoshi389111/pong-is-not-ping-323d</link>
      <guid>https://dev.to/yoshi389111/pong-is-not-ping-323d</guid>
      <description>&lt;p&gt;I created the pong command in Go language.&lt;/p&gt;

&lt;p&gt;See below for a run-time image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdC9etL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/yoshi389111/pong-is-not-ping/raw/main/docs/pong.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdC9etL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/yoshi389111/pong-is-not-ping/raw/main/docs/pong.gif" alt="demo" width="549" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command was inspired by the existing awesome pong command.&lt;/p&gt;

&lt;p&gt;That awesome pong command was created by &lt;a href="https://github.com/kurehajime"&gt;kurehajime&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/kurehajime"&gt;
        kurehajime
      &lt;/a&gt; / &lt;a href="https://github.com/kurehajime/pong-command"&gt;
        pong-command
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      pong is not ping.   pong is CLI game.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
pong-command&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/4569916/7273449/e6c410be-e92e-11e4-89dd-ba6903089706.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Ylcby3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cloud.githubusercontent.com/assets/4569916/7273449/e6c410be-e92e-11e4-89dd-ba6903089706.gif" alt="pong"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pong-command is a CLI game.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO&lt;/strong&gt;ng is &lt;strong&gt;N&lt;/strong&gt;ot pin&lt;strong&gt;G&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
How to use.&lt;/h2&gt;
&lt;h3&gt;
1. Download Win/Mac OSX/Linux binary&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/kurehajime/pong-command/releases"&gt;Download here. Windows,MacOSX,Linux,BSD binary&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
2. Move file or Add directory to PATH&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Mac OSX / Linux :&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Copy a file into /usr/local/bin&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cp ./pong /usr/local/bin/pong
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Windows :&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.nextofwindows.com/how-to-addedit-environment-variables-in-windows-7/" rel="nofollow"&gt;Add directory to PATH Environment Variable&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
3. pong&lt;/h3&gt;
&lt;p&gt;Run command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$./pong &amp;lt;IP Address&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Start game.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;
                                                                     006 - 000
--------------------------------------------------------------------------------








                                                                      1
                                                                        9   ||
                                                                          2 ||
  ||                                                                      . ||
  ||                                                                    1   ||
  ||                                                                  6
  ||                                                                8
                                                                  .
                                                                1
                                                              .
                                                            1


--------------------------------------------------------------------------------
EXIT : ESC KEY


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
... or install by 'go install'&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go install github.com/kurehajime/pong-command/pong@latest
&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
LICENSE&lt;/h2&gt;
&lt;p&gt;This software is released under the MIT License, see LICENSE.txt.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kurehajime/pong-command"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;In this pong command, the target hostname you enter will take the place of the ball.&lt;/p&gt;

&lt;p&gt;Sounds like a great idea, doesn't it?&lt;/p&gt;

&lt;p&gt;The key types for &lt;code&gt;pong&lt;/code&gt; and &lt;code&gt;ping&lt;/code&gt; are similar (&lt;code&gt;O&lt;/code&gt; and &lt;code&gt;I&lt;/code&gt; next to each other in QWERTY).&lt;br&gt;
Therefore, I feel that it is similar to the key type correction effect of the &lt;code&gt;sl&lt;/code&gt; command for the &lt;code&gt;ls&lt;/code&gt; command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu manuals: &lt;a href="https://manpages.ubuntu.com/manpages/bionic/man6/sl.6.html"&gt;sl(6)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you thought the above article and command ideas were great, I encourage you to star the &lt;a href="https://github.com/kurehajime/pong-command"&gt;repository&lt;/a&gt; before reading the rest of the text.&lt;/p&gt;

&lt;p&gt;When I saw this command, I thought, "Great idea."&lt;br&gt;
However, at the same time, I thought, "Is there another possibility?"&lt;/p&gt;

&lt;p&gt;So let's start by looking at the pong game and the ping command.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is pong game?
&lt;/h2&gt;

&lt;p&gt;It is a game like so-called table tennis (ping pong).&lt;br&gt;
Various pong games have been created since recorded history.&lt;/p&gt;


&lt;div class="ltag__wikipedia--container"&gt;
  &lt;div class="ltag__wikipedia--header"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Y-xY3vU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/wikipedia-logo-0a3e76624c7b1c3ccdeb9493ea4add6ef5bd82d7e88d102d5ddfd7c981efa2e7.svg" class="ltag__wikipedia--logo" alt="Wikipedia Logo" width="128" height="128"&gt;
    &lt;a href="https://en.wikipedia.org/wiki/Pong" rel="noopener noreferrer"&gt;Pong&lt;/a&gt;
  &lt;/div&gt;
  &lt;div class="ltag__wikipedia--extract"&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;Pong&lt;/b&gt;&lt;/i&gt; is a table tennis–themed twitch arcade sports video game, featuring simple two-dimensional graphics, manufactured by Atari and originally released in 1972. It was one of the earliest arcade video games; it was created by Allan Alcorn as a training exercise assigned to him by Atari co-founder Nolan Bushnell, but Bushnell and Atari co-founder Ted Dabney were surprised by the quality of Alcorn's work and decided to manufacture the game. Bushnell based the game's concept on an electronic ping-pong game included in the Magnavox Odyssey, the first home video game console. In response, Magnavox later sued Atari for patent infringement.&lt;/p&gt;&lt;/div&gt;
  &lt;div class="ltag__wikipedia--btn--container"&gt;
    
      &lt;a href="https://en.wikipedia.org/wiki/Pong" rel="noopener noreferrer"&gt;View on Wikipedia&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It is common for two players to play against each other, or for users against computers.&lt;br&gt;
There are paddles (or racquets) on the left and right (or top and bottom) of the screen, and players operate the paddles to hit the ball.&lt;/p&gt;

&lt;p&gt;I think it is no exaggeration to say that it is probably the beginning of e-sports.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the ping command?
&lt;/h2&gt;

&lt;p&gt;The ping command is a command that checks whether there is a response from a device with a specific IP address on the IP network.&lt;/p&gt;

&lt;p&gt;The ping command is usually executed by specifying the target host (IP address or hostname).&lt;/p&gt;

&lt;p&gt;The executed ping command will send an ICMP protocol echo request packet towards the target.&lt;br&gt;
When the target host receives an ICMP echo request packet, it returns an echo reply packet to the source (some hosts do not respond due to settings, etc.).&lt;/p&gt;

&lt;p&gt;If the target host is not on the same network, the gateway between networks will relay the echo request/reply packets. At that time, the TTL (Time To Live) value in the packet is decremented by 1, and if the result of the decrement is 0, the packet is not relayed and discarded.&lt;/p&gt;

&lt;p&gt;The ping command records network reachability, response time, etc. by receiving or not returning an ICMP echo reply from the target host.&lt;/p&gt;

&lt;p&gt;Depending on the execution environment and option specification, it sends and receives ICMP echo packets for a specified number of times or until the user stops (such as CTRL+C), and finally reports the result.&lt;/p&gt;


&lt;div class="ltag__wikipedia--container"&gt;
  &lt;div class="ltag__wikipedia--header"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Y-xY3vU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/wikipedia-logo-0a3e76624c7b1c3ccdeb9493ea4add6ef5bd82d7e88d102d5ddfd7c981efa2e7.svg" class="ltag__wikipedia--logo" alt="Wikipedia Logo" width="128" height="128"&gt;
    &lt;a href="https://en.wikipedia.org/wiki/Ping_(networking_utility)" rel="noopener noreferrer"&gt;Ping (networking utility)&lt;/a&gt;
  &lt;/div&gt;
  &lt;div class="ltag__wikipedia--extract"&gt;&lt;p&gt;&lt;b&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/b&gt; is a computer network administration software utility used to test the reachability of a host on an Internet Protocol (IP) network. It is available for virtually all operating systems that have networking capability, including most embedded network administration software.&lt;/p&gt;&lt;/div&gt;
  &lt;div class="ltag__wikipedia--btn--container"&gt;
    
      &lt;a href="https://en.wikipedia.org/wiki/Ping_(networking_utility)" rel="noopener noreferrer"&gt;View on Wikipedia&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  I created the pong command.
&lt;/h2&gt;

&lt;p&gt;After examining the similarities and differences between the pong game and the ping command, I created the pong command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdC9etL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/yoshi389111/pong-is-not-ping/raw/main/docs/pong.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdC9etL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/yoshi389111/pong-is-not-ping/raw/main/docs/pong.gif" alt="demo" width="549" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you run the pong command with a target host, the local host (on the far left of the screen) will send an ICMP ECHO packet.&lt;/p&gt;

&lt;p&gt;On the target host (the paddle you control on the right), take the incoming ICMP ECHO packets and send them back to the host that sent them (the localhost on the far left).&lt;/p&gt;

&lt;p&gt;However, the Gateway (the paddle on the left side of the screen, operated by the computer) in between, for whatever reason, always sends it back to the target host when it receives an ICMP ECHO packet.&lt;br&gt;
So you need to send an ICMP ECHO packet back to the localhost while avoiding the Gateway.&lt;br&gt;
When the Gateway sends back, the TTL is decremented, so send it back before the TTL runs out (by default the TTL starts from 64).&lt;/p&gt;

&lt;p&gt;Also, if you send back many times, the network speed will gradually increase. be careful.&lt;/p&gt;

&lt;p&gt;By default, the local host will send ICMP ECHO packets 4 times.&lt;br&gt;
After the last packet has been received (or lost), or if the user has stopped, display packet response state statistics up to that point.&lt;/p&gt;

&lt;p&gt;The starting method of this pong command is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pong [options] &amp;lt;destination&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The following can be specified as options.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application Options:
  -h, --help                 print help and exit
  -v, --version              print version and exit
  -c, --count=&amp;lt;count&amp;gt;        stop after &amp;lt;count&amp;gt; replies (default: 4)
  -t, --ttl=&amp;lt;ttl&amp;gt;            define time to live (default: 64)
  -p, --padding=&amp;lt;pattern&amp;gt;    contents of padding byte

Arguments:
  &amp;lt;destination&amp;gt;:             dns name or ip address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The source code is on GitHub.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yoshi389111"&gt;
        yoshi389111
      &lt;/a&gt; / &lt;a href="https://github.com/yoshi389111/pong-is-not-ping"&gt;
        pong-is-not-ping
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      POng is Not pinG
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Pong-is-not-Ping&lt;/h1&gt;
&lt;p&gt;This command is pong game.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO&lt;/strong&gt;ng is &lt;strong&gt;N&lt;/strong&gt;ot pin&lt;strong&gt;G&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Inspired by &lt;a href="https://github.com/kurehajime/pong-command"&gt;kurehajime/pong-command&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/yoshi389111/pong-is-not-ping./docs/pong.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gA8OqzBx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/yoshi389111/pong-is-not-ping./docs/pong.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;go install github.com/yoshi389111/pong-is-not-ping/cmd/pong@latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;h3&gt;
Usage:&lt;/h3&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;  pong [options] &amp;lt;destination&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
Options:&lt;/h3&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;Application Options:
  -h, --help                 print help and exit
  -v, --version              print version and exit
  -c, --count=&amp;lt;count&amp;gt;        stop after &amp;lt;count&amp;gt; replies (default: 4)
  -t, --ttl=&amp;lt;ttl&amp;gt;            define time to live (default: 64)
  -p, --padding=&amp;lt;pattern&amp;gt;    contents of padding byte

Arguments:
  &amp;lt;destination&amp;gt;:             dns name or ip address
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Copyright and License&lt;/h2&gt;
&lt;p&gt;(C) 2022 SATO, Yoshiyuki&lt;/p&gt;
&lt;p&gt;This software is released under the MIT License.&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yoshi389111/pong-is-not-ping"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;The Japanese version of this article is below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qiita: &lt;a href="https://qiita.com/yoshi389111/items/a289f1c470616c5f10c4"&gt;Go言語でpingコマンドっぽい、でもpingコマンドじゃないpongコマンドを作ってみた&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>ping</category>
      <category>pong</category>
      <category>jokes</category>
    </item>
    <item>
      <title>I made a VSCode extension: "markdown-table-rainbow"</title>
      <dc:creator>SATO, Yoshiyuki</dc:creator>
      <pubDate>Sat, 22 Apr 2023 05:03:28 +0000</pubDate>
      <link>https://dev.to/yoshi389111/i-made-a-vscode-extension-markdown-table-rainbow-4l27</link>
      <guid>https://dev.to/yoshi389111/i-made-a-vscode-extension-markdown-table-rainbow-4l27</guid>
      <description>&lt;p&gt;Last month when I was writing Markdown, I thought it would be easier to understand if each column in the table had its own color, so I made a VSCode extension that colors the columns in the table.&lt;/p&gt;

&lt;p&gt;Of course, I knew there were extensions to format Markdown tables, but I have a problem when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the table has very long items and formatting makes them too wide&lt;/li&gt;
&lt;li&gt;When CKJ characters are used and formatting does not align well&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As far as I know, I haven't found an extension with similar functionality.&lt;/p&gt;

&lt;p&gt;This extension is published on the marketplace.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;marketplace: &lt;a href="https://marketplace.visualstudio.com/items?itemName=yoshi389111.markdown-table-rainbow" rel="noopener noreferrer"&gt;markdown-table-rainbow&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The source code is on GitHub.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yoshi389111" rel="noopener noreferrer"&gt;
        yoshi389111
      &lt;/a&gt; / &lt;a href="https://github.com/yoshi389111/vscode-md-table-rainbow" rel="noopener noreferrer"&gt;
        vscode-md-table-rainbow
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A VS Code extension that colorizes table columns in Markdown for clarity.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;markdown-table-rainbow&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;An extension that colorizes table columns in Markdown for clarity.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This extension colors by columns in markdown tables.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/yoshi389111/vscode-md-table-rainbowassets/demo.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyoshi389111%2Fvscode-md-table-rainbowassets%2Fdemo.gif" alt="demo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Extension Settings&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;You can use it without any setting.
However, you can also change:&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;  &lt;span class="pl-c"&gt;// Delay time in milliseconds before updating colors.&lt;/span&gt;
  &lt;span class="pl-c"&gt;// Smaller values will color faster, but will increase processing cost.&lt;/span&gt;
  &lt;span class="pl-s"&gt;"markdownTableRainbow.updateDelay"&lt;/span&gt;: &lt;span class="pl-c1"&gt;100&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c"&gt;// An array of color strings (hex, rgba, rgb) for each column.&lt;/span&gt;
  &lt;span class="pl-c"&gt;// You can specify any number of colors. used cyclically.&lt;/span&gt;
  &lt;span class="pl-s"&gt;"markdownTableRainbow.colors"&lt;/span&gt;: &lt;span class="pl-kos"&gt;[&lt;/span&gt;
    &lt;span class="pl-s"&gt;"rgba(79,236,236,0.1)"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"rgba(255,255,63,0.1)"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"rgba(127,255,127,0.1)"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"rgba(255,127,255,0.1)"&lt;/span&gt;
  &lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c"&gt;// Cursor column color strings (hex, rgba, rgb).&lt;/span&gt;
  &lt;span class="pl-s"&gt;"markdownTableRainbow.cursorColor"&lt;/span&gt;: &lt;span class="pl-s"&gt;"rgba(100,50,180,0.8)"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yoshi389111/vscode-md-table-rainbow" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How to install
&lt;/h2&gt;

&lt;p&gt;Download it from the marketplace or search for &lt;code&gt;markdown-table-rainbow&lt;/code&gt; in VSCode Extensions and install it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;This extension colors by columns in markdown tables.&lt;/p&gt;

&lt;p&gt;Also, when the cursor is on a table column, all columns at the same position as the corresponding column are colored.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyoshi389111%2Fvscode-md-table-rainbow%2Fraw%2FHEAD%2Fassets%2Fdemo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyoshi389111%2Fvscode-md-table-rainbow%2Fraw%2FHEAD%2Fassets%2Fdemo.gif" alt="demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extension Settings
&lt;/h2&gt;

&lt;p&gt;You can use it without any setting. However, you can also change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// Delay time in milliseconds before updating colors.&lt;/span&gt;
  &lt;span class="c1"&gt;// Smaller values will color faster, but will increase processing cost.&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdownTableRainbow.updateDelay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// An array of color strings (hex, rgba, rgb) for each column.&lt;/span&gt;
  &lt;span class="c1"&gt;// You can specify any number of colors. used cyclically.&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdownTableRainbow.colors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(79,236,236,0.1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(255,255,63,0.1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(127,255,127,0.1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(255,127,255,0.1)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// Cursor column color strings (hex, rgba, rgb).&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdownTableRainbow.cursorColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(100,50,180,0.8)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  markdownTableRainbow.updateDelay
&lt;/h3&gt;

&lt;p&gt;Specifies the delay time in milliseconds before updating. When not specified, it operates as 100ms.&lt;/p&gt;

&lt;p&gt;Smaller values will color faster, but will increase processing cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  markdownTableRainbow.colors
&lt;/h3&gt;

&lt;p&gt;Specifies a list (array) of background colors for each column in the table.&lt;br&gt;
If not specified, the default color will be used.&lt;br&gt;
Cycles through the specified list if the number of columns in the table is greater than the array length.&lt;/p&gt;

&lt;p&gt;The colors that can be specified are as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#RRGGBB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rgb(R, G, B)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rgba(R, G, B, A)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  markdownTableRainbow.cursorColor
&lt;/h3&gt;

&lt;p&gt;Specifies the color of the column at the same position as the cursor position.&lt;/p&gt;

&lt;p&gt;The colors that can be specified are the same as &lt;code&gt;markdownTableRainbow.colors&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sites used as reference for creation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/api/references/vscode-api" rel="noopener noreferrer"&gt;official VSCode API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/vscode-extension-samples/tree/main/decorator-sample" rel="noopener noreferrer"&gt;Official sample extension (Decorator)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Miscellaneous Notes
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Parsing Markdown
&lt;/h3&gt;

&lt;p&gt;When I first came up with this extension, I thought I would have to use a library to parse the structure of Markdown.&lt;br&gt;
However, when I checked some sources of extension functions for manipulating Markdown tables, I couldn't find any that used such a library.&lt;br&gt;
So I decided to use regular expressions for table-like expressions, i.e. rows containing &lt;code&gt;|&lt;/code&gt;  at the beginning of a line and multiple &lt;code&gt;|&lt;/code&gt; on the same line.&lt;/p&gt;

&lt;p&gt;Lines starting with &lt;code&gt;&amp;gt;&lt;/code&gt; are also included to account for tables within quoted blocks.&lt;/p&gt;

&lt;p&gt;So, for example, if there is a Markdown table description inside a code block, it will be misidentified as a table as well. This is the intended behavior.&lt;/p&gt;
&lt;h3&gt;
  
  
  range to color
&lt;/h3&gt;

&lt;p&gt;This time, the range of columns to be colored is inclusive of the leading &lt;code&gt;|&lt;/code&gt; and not including the trailing &lt;code&gt;|&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At first, I thought it would be better not to include both, but I found an article that says that depending on the type of markdown, colspan-like things can be written like &lt;code&gt;| here is a two-column join ||&lt;/code&gt;.&lt;br&gt;
Therefore, I thought that it would be difficult to understand if the column color was not displayed at all, so I put a &lt;code&gt;|&lt;/code&gt; on one side.&lt;/p&gt;

&lt;p&gt;I could have included either before or after, but for now I included the previous &lt;code&gt;|&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  About resource dispose
&lt;/h3&gt;

&lt;p&gt;In the official sample code mentioned above, we only create an instance of &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt;, which is a definition for decoration, and do not do anything particularly post-processing.&lt;/p&gt;

&lt;p&gt;But if you look at the source of &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt; there is a &lt;code&gt;dispose()&lt;/code&gt; method.&lt;br&gt;
It may not be a problem if I don't call it, but it bothers me so I called &lt;code&gt;dispose()&lt;/code&gt; at the end.&lt;/p&gt;

&lt;p&gt;Just register it with the instance of &lt;code&gt;vscode.ExtensionContext&lt;/code&gt; that is passed when &lt;code&gt;activate()&lt;/code&gt; is called, and it will be processed when it is no longer needed.&lt;/p&gt;
&lt;h3&gt;
  
  
  rangeBehavior
&lt;/h3&gt;

&lt;p&gt;By default, the decoration range of VSCode is a specification that if you add a character immediately before or after it, the added character will also be included in the decoration range.&lt;/p&gt;

&lt;p&gt;Specifically, the &lt;code&gt;rangeBehavior&lt;/code&gt; specified in &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt; is &lt;code&gt;OpenOpen&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;In this extension, &lt;code&gt;|&lt;/code&gt; in front of the column is included in the decoration range, but when a character is added before that, it is strange that the added character will be colored in the column behind it, so marked &lt;code&gt;Closed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the trailing &lt;code&gt;|&lt;/code&gt; is not included in the decoration range, it is often better to input immediately after the decoration range (that is, before &lt;code&gt;|&lt;/code&gt;) in the column color, so immediately after I left it as &lt;code&gt;Open&lt;/code&gt; (the exception is when entering a new &lt;code&gt;|&lt;/code&gt;, but in that case, I decided that rewriting after the delay would not be a problem).&lt;/p&gt;

&lt;p&gt;Now specifies &lt;code&gt;ClosedOpen&lt;/code&gt; as result.&lt;/p&gt;
&lt;h3&gt;
  
  
  Loading timing of setting items
&lt;/h3&gt;

&lt;p&gt;At first, like the official sample, I looked at the config when &lt;code&gt;activate()&lt;/code&gt; was called and generated a definition for &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, with this, even if the user rewrites &lt;code&gt;settings.json&lt;/code&gt;, it will continue to work with the old definition unless &lt;code&gt;activate()&lt;/code&gt; is called again. And since it is not called normally, it will not be reflected unless you restart.&lt;/p&gt;

&lt;p&gt;Therefore, &lt;code&gt;vscode.workspace.onDidChangeConfiguration()&lt;/code&gt; detects the configuration change and recreates the &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt; object again.&lt;/p&gt;

&lt;p&gt;By the way, &lt;code&gt;vscode.TextEditorDecorationType&lt;/code&gt; is registered in &lt;code&gt;context.subscriptions&lt;/code&gt; in order to &lt;code&gt;dispose()&lt;/code&gt; at the end of processing.&lt;br&gt;
It may not be such a problem, but it is annoying to keep unnecessary resources all the time, and if you change the configuration many times, it will be registered many times, so when you recreate it, Added processing to remove the previous object from &lt;code&gt;context.subscriptions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I'm not sure if this method is the best.&lt;/p&gt;
&lt;h3&gt;
  
  
  Checking config array values
&lt;/h3&gt;

&lt;p&gt;In the case of items defined from the setting screen, even if they are of &lt;code&gt;string&lt;/code&gt; type, for example, they can be checked with regular expressions (regular expressions can be specified in the &lt;code&gt;pattern&lt;/code&gt; of the property definition in &lt;code&gt;package.json&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;However, this time, the background color is defined as an array type, and it is necessary to have it listed directly in &lt;code&gt;settings.json&lt;/code&gt;, so the format check cannot be applied as it is.&lt;/p&gt;

&lt;p&gt;Therefore, I detected the configuration change with &lt;code&gt;vscode.workspace.onDidChangeConfiguration()&lt;/code&gt; mentioned above and applied a format check when recreating the resource.&lt;/p&gt;

&lt;p&gt;At that time, I am currently preparing a long regular expression and checking whether it matches.&lt;br&gt;
Actually, I feel that it would be better to divide it into several short regular expressions or check it with logic instead of doing everything with regular expressions (for example, if the value of &lt;code&gt;R&lt;/code&gt;/&lt;code&gt;G&lt;/code&gt;/&lt;code&gt;B&lt;/code&gt; is 0 to 255 is easier to do with logic than with a regular expression). This is because I thought that the regular expression could be used in common if I checked the format with the definition (&lt;code&gt;pattern&lt;/code&gt;) of &lt;code&gt;package.json&lt;/code&gt; and checked both with regular expressions.&lt;br&gt;
In the future, when I increase other patterns, I just copy the same value for both.&lt;/p&gt;

&lt;p&gt;Therefore, the JavaScript regular expression is defined like &lt;code&gt;new RegExp("RE")&lt;/code&gt; instead of &lt;code&gt;/RE/&lt;/code&gt; (the other one defines it as a string in &lt;code&gt;package.json&lt;/code&gt;, so use the same format wanted).&lt;/p&gt;
&lt;h3&gt;
  
  
  How to get config
&lt;/h3&gt;

&lt;p&gt;I saw a source that acquired the config as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myExtension&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateDelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updateDelay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This still works, but in this case the value returned by &lt;code&gt;config[]&lt;/code&gt; is of the form &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking at the API specifications, there is a method called &lt;code&gt;get()&lt;/code&gt;, which seems to allow you to specify a generic type and specify a default value in the method. Of course, it is necessary to describe it with consistency between the definition and the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myExtension&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateDelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updateDelay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Filtering documents of interest
&lt;/h3&gt;

&lt;p&gt;At first, I misunderstood, and if I registered &lt;code&gt;onLanguage:markdown&lt;/code&gt; in &lt;code&gt;activationEvents&lt;/code&gt; of &lt;code&gt;package.json&lt;/code&gt;, I thought that the event would be notified only in Markdown, but apparently it is activated when a Markdown file is opened. Subsequent events seem to be notified regardless of document type.&lt;/p&gt;

&lt;p&gt;So before processing the target &lt;code&gt;editor&lt;/code&gt; we need to check if the document is target like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;languageId&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;markdown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I thought this would be fine, but I thought it would be troublesome to have to modify both &lt;code&gt;package.json&lt;/code&gt; and this logic if I wanted to process files other than &lt;code&gt;markdown&lt;/code&gt; in the future.&lt;/p&gt;

&lt;p&gt;It seems that &lt;code&gt;context.extension.packageJSON&lt;/code&gt; can get the contents of the extension's &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
(Although he seems to be able to get other extensions with &lt;code&gt;vscode.extensions.getExtension()&lt;/code&gt;. The key seems to be specified like &lt;code&gt;"&amp;lt;publisher name&amp;gt;.&amp;lt;extension name&amp;gt;"&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;So I tried the following. The current situation is over spec.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onLanguages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activationEvents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onLanguage:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onLanguage:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;onLanguages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;languageId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, are there any languages other than &lt;code&gt;markdown&lt;/code&gt; that should be supported?&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimum version of VSCode
&lt;/h3&gt;

&lt;p&gt;There is a place to describe the minimum version of VSCode that works in &lt;code&gt;engines&lt;/code&gt; of &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;engines&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vscode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^1.76.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This extension does not use any new features, so it should work even on very old versions.&lt;br&gt;
However, I don't know how to test with older versions, so I specified the latest version at the time.&lt;/p&gt;

&lt;p&gt;Is it usually the one that specifies the latest version?&lt;/p&gt;

&lt;h3&gt;
  
  
  Japanese version of this document
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Qiita: &lt;a href="https://qiita.com/yoshi389111/items/bd6435ef6830742e4d9d" rel="noopener noreferrer"&gt;Markdownのテーブルの列に色付けするVSCode拡張機能を作ったよ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>vscode</category>
      <category>extension</category>
      <category>markdown</category>
    </item>
  </channel>
</rss>
