俺的 codeほにゃらら:SJIS⇔EUC 文字コード変換

必要に迫られて自前で書いてみたらなんかへタレなコードしか書けなくて、素で絶望した! 10年前よりマジでプログラミング能力落ちてるな!

たとえば C(++) でスマートなコードということになると、このへんになるのでしょうか。

ちなみに自分で1から書いてみたやつ(上のとだいたい同じ流儀で切り出して書き直した)。

inline void EUCtoSJIS( u_char& knj1, u_char& knj2 )
{
  if (knj1 & 1) {
    knj2 = (knj2 - 0xa1) + 0x40;
    if (knj2 > 0x7e) knj2++;
  } else
    knj2 = knj2 - 0xa1 + 0x9f;
  knj1 = (((knj1 - 0x21) & 0x7e) >> 1) + 0x81;
  if (knj1 > 0x9f) knj1 += 0xe0 - 0xa0;
}

inline void SJIStoEUC( u_char& knj1, u_char& knj2 )
{
  knj1 = ((knj1 - 0x81) << 1) + 0xa1;
  if (knj2 <= 0x9e) {
    if (knj2 >= 0x80) --knj2;
    knj2 = knj2 - 0x40 + 0xa1;
  } else {
    knj1++;
    knj2 = knj2 - 0x9f + 0xa1;
  }
}

定数の畳み込みとか全然してない(自分で自分のやったことがわからなくなるから)あたりが脳味噌のくたびれっぷりをもう如実に

そういえば昔(パソ通時代)に読んだ漢字コードに関する資料の中にかなりタイトなアセンブラのコードが載ってたような気がするので探してみた。以下「コンピュータの漢字コードに関する資料 Ver.5.0」からの引用。(メンテナの清十郎さんのページで落とせるかと思ったらなかった。検索かけると見つかりますが、バージョンが古いテキストだとコードが載ってないヨ…)

〇SJIS<−>JIS変換

;shift-jis -> jis は moritanさん作で16バイトです.
tojis:					;Shift-JIS(AH:AL)をJIS・コードに変換
	shl	ah,1
	sub	al,1fh
	js	tj0
	cmp	al,61h
	adc	al,0deh
tj0:
	add	ax,1fa1h
	and	ax,7f7fh
	ret

;shift-jis -> jis は Q太郎さん作で16バイトです.
sjis_jis:				;Shift-JIS(AL:AH)をJIS・コードに変換
        and     al,3fh
        shl     al,1
        sub     ah,9fh
        jae     sj0
        cmp     ah,0e1h
        adc     ah,5eh
sj0:
        sbb     ax,0dee0h		;(0dee0h+20h)PC98 ディスプレイコードに変換
	ret

;jis -> shift-jis は わかんさん作で14バイトです.
tosjis:					;JIS(AH:AL)をShift-JIS・コードに変換
	add	ax,0a17eh
	shr	ah,1
	jb	tsj0
	cmp	al,0deh
	sbb	al,5eh
tsj0:
	xor	ah,0e0h
	ret

;jis -> shift-jis は 清十郎で15バイトです.
jis_sjis:				;JIS(AL:AH)をShift-JIS・コードに変換
	add	ax,7e21h
	shr	al,1
	jb	js0
	cmp	ah,0deh
	sbb	ah,5eh
js0:
	xor	al,0a0h
	ret

こういうの見ると、アセンブラってやっぱパズル脳だよなあとか思ったりする(cmp 後のキャリー演算はまあ分岐削りの定番テクではあるのですが…)。