vb6 win2000
例 あいうえお
と入力されたら一文字づつ抜き出してasc()に変換して+1してchr()で変換して表示しています。
http://www.infonet.co.jp/ueyama/ip/binary/x0208txt.html
のJISコードを参考にしてやっているのですが『ん』とか最後(右端)にくる文字が『・』に変えられてしまい(次の文字が無い為)変換した後に元に戻す(chr(asc()-1))ことが出来ません。
なにか良い対策がありましたら教えて下さい。
>なにか良い対策がありましたら教えて下さい。
対策と言われても何に使いたいか判らないと難しいな。。。
簡易の暗号か何かでしょうか?
『・』が出てきたら文字が出るまで、Asc()をインクリメントするとか。
戻す場合は『・』が出てきたら文字が出るまでディクリメントするとか。
これで一応可逆性は保てますが。
最初と最後をくっ付けることを忘れないように。
chrに変換するのではなく、asc()の値を保持してればいいのでは?
Option Explicit
Private moji() As Long
Private Sub Form_Load()
Text1.Text = "あいうえお"
End Sub
'変換
Private Sub Command1_Click()
Dim i As Integer
ReDim moji(1 To Len(Text1.Text))
For i = 1 To Len(Text1.Text)
moji(i) = Asc(Mid$(Text1.Text, i, 1)) + 1
Next i
Text2.Text = ""
For i = LBound(moji) To UBound(moji)
Text2.Text = Text2.Text & Chr(moji(i))
Next i
End Sub
'元に戻す
Private Sub Command2_Click()
Dim i As Integer
Text2.Text = ""
For i = LBound(moji) To UBound(moji)
Text2.Text = Text2.Text & Chr(moji(i) - 1)
Next i
End Sub
ねろさん、LESIAさん ありがとうございます。
>最初と最後をくっ付けることを忘れないように。
ねろさんすいませんが意味がわからないのですが・・・
LESIAさん簡易暗号ですのでchr()に変換したいのです。
>『・』が出てきたら文字が出るまで、Asc()をインクリメントするとか。
ねろさんのアドバイスですと文字がなくなってしまいます(*.*);
Private Sub Command1_Click()
Dim str As String
Dim strDummy As String
Dim i As Long
Dim a As Long
Dim strPW As String
strPW = vbNullString
str = Text1.Text
For i = 1& To Len(str)
strDummy = Chr(Asc(str) + 1)
If strDummy <> "・" Then
strPW = strPW & Chr(Asc(str) + 1)
Else
a = 1
Do
a = a + 1
strDummy = Chr(Asc(str) + a)
If strDummy <> "・" Then
strPW = strPW & Chr(Asc(str) + a)
Exit Do
End If
Loop
End If
Next i
Text1.Text = strPW
MsgBox strPW
End Sub
Private Sub Form_Load()
Text1.Text = "わ"
End Sub
>『・』が出てきたら文字が出るまで、Asc()をインクリメントするとか。
ねろさんのアドバイスですと文字がなくなってしまいます(*.*);
だから
>最初と最後をくっ付けることを忘れないように。
ということです。
つまり文字がなくなったら、Ascコードを最初の文字のにするということです。
元に戻す時は、『・』が出てきたら文字が出るまで、Asc()をデクリメントして
文字がなくなったら、最後の文字にします。
使用可能な文字コードの範囲には、限りがありますよね。
なので、その範囲内でやり繰りする必要がある事を念頭に置いて下さい。
たとえば、A〜Zの範囲だけで考えてみると、文字コードは
A→&H41, B→&H42, ……, Y→&H59, Z→&H5A
のようになっていますよね。
これを、単純に +1 だけずらす(シフトさせる)という事は、
A→&H42, B→&H43, ……, Y→&H5A, Z→&H5B
のようにするのではなく、
A→&H42, B→&H43, ……, Y→&H5A, Z→&H41
のように、最初と最後を繋げておく必要があるわけです。
もちろん、実際に使う文字は A〜Z よりも多いですし、
使われていないコード領域もありますから、それらを
考慮する必要がありますけれどね。
もう一つの案としては、元データの「1文字」を「別の1文字」に
置き換えるのではなく、「複数の文字」で表現するという手法があります。
たとえば AscW("あ") からは &H82A0 という値が返されますが、
これを "82A0" の4文字で表現すれば、(文字列長は増加しますが)
文字列を正しく暗号化/復元可能である事はわかりますよね。
ここでは、Hex関数を使って 16進数で表現しているため、1文字につき
4バイトが消費されてしまいますが、これを26進数にしたり、90進数に
したりすれば、必要なデータ量はさらに圧縮できるというわけです。
たとえば、メールの配信などに利用される、『BASE64』という
バイナリ→テキスト変換方式では、3バイト(24bit)のデータを
6bit単位で4つに区切る事で、あらゆるデータを4バイト単位の
テキストに変換できるようになっています。
(6bitなら、0〜63の種類に収まるので、ASCIIの範囲で十分に表現可能)
LESIAさん、レスありがとう。(^^
魔界の仮面弁士さんの格調高い説明の後で書きにくいんだけど、
けじめをつける意味で。
こういうのはFunctionを使った方がいいよ。
Private Function Encode(ByVal s As String) As String
Dim AscNo As Integer
AscNo = Asc(s)
Do
If AscNo >= Asc("熙") Then
AscNo = Asc("、")
Else
AscNo = AscNo + 1
End If
Loop While (AscNo <> Asc(Chr(AscNo)) Or Chr(AscNo) = " " Or Chr(AscNo) = " ")
Encode = Chr(AscNo)
End Function
Private Function Decode(ByVal s As String) As String
Dim AscNo As Integer
AscNo = Asc(s)
Do
If AscNo < Asc("、") Then
AscNo = Asc("熙")
Else
AscNo = AscNo - 1
End If
Loop While (AscNo <> Asc(Chr(AscNo)) Or Chr(AscNo) = " " Or Chr(AscNo) = " ")
Decode = Chr(AscNo)
End Function
可逆性があるかどうかは
>If strDummy <> "・" Then
よりも AscNo <> Asc(Chr(AscNo)) の方がいいかな。
Chr(AscNo) = " " Or Chr(AscNo) = " "
半角と全角のスペースも暗号には不向きなのでこれもスキップ、テキストボックスの方でも
入力できないようにする。
ただし当方文字コードについてはかなり疎い、何かとんでもない落とし穴があるような。。
ねろさん、LESIAさん、魔界の仮面弁士さん
ありがとうございます。
みなさんのアドバイス(事細かな説明)で理解できました。
まだ完成にはいたっておりませんが、回避策が見えてきましたので解決とさせて頂きます。
チェック付け忘れました(^.^;)
ツイート | ![]() |