仮に、
「た」 ⇔ 「01001001」みたいに相互変換する方法か、もしくは関数が知りたいです。
2進数、という呼び方でいいのかもわからない素人ですけど、要は0と1のstring型で戻り値が欲しいのです。
どなたかお願いします。
一発変換はないと思います。
下記で文字→2進数はできました。逆は調べていません。
あと考え方間違ってればどなたかつっこみお願いします。
※「た」 をいれると 1000001010111101 が帰ってきます。
文字→16進数
https://www.petitmonte.com/bbs/answers?question_id=6468
16進数→10進数
IntToStr関数
※変換したい16進数に $ を付けてください。
10進数→2進数
http://www2.big.or.jp/~osamu/Delphi/tips.cgi?index=0225.txt
この方のサイトに16進数を2進数にする関数がありまして、これによりますと、私もRuさんと同じく、「た」は1000001010111101となりました。
http://www.tanaka-software.jp/tips-d003.php
ここで、1000001010111101から16進数にするには、上記サイトのBinToHex関数を使わせてもらうとして、今度は16進数から文字列に戻す方法でいきづまっている所です。
文字列を16進数にする方法はWeb上で多く見られるのですが、逆はなかなか見つかりません。
テーブル引き? になるんでしょうか?
いわば、HexToString関数のようなものがあればいいのですが、ググってもPHP用のしかみつけられませんでした。
キャストしたりする方法はないんでしょうか?
16進→数値: 頭に'$'を付けてStrToIntとかValとか
数値→文字: Chr
2バイト文字だと上位と下位に分けて変換してからくっつける必要があるかも。
(分けるのはシフト演算使ってもいいですが、Lo, Hi で手軽にできます)
こんにちは。
以下のような物でどうでしょうか?
function StrToBin(S: String): String;
var
i: Integer;
Buf: String;
ii: Integer;
begin
//SJIS -> 2進数
Result := '';
for i := 1 to Length(S) do
begin
SetLength(Buf,8);
for ii := 8 downto 1 do
begin
Buf[ii] := IntToStr((Ord(S[i]) shr (8-ii)) mod 2)[1];
end;
Result := Result + Buf;
end;
end;
function BinToStr(S: String): String;
var
i: Integer;
Buf: Byte;
begin
//2進数 -> SJIS
Result := '';
Buf := 0;
if Length(S) mod 8 = 0 then
begin
for i := 1 to Length(S) do
begin
if i mod 8 = 1 then Buf := 0;
if S[i] = #$31 then
begin
if i mod 8 = 0 then
begin
Buf := Buf + 1;
end
else
begin
Buf := Buf + Trunc(Power(2,8 - (i mod 8)));
end;
end;
if i mod 8 = 0 then Result := Result + AnsiChar(Buf);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
S,BS: String;
begin
//使用例
S := 'た';
BS := StrToBin(S);
ShowMessage(BS);//1000001010111101
ShowMessage(BinToStr(BS));//た
end;
D2007までのDelphiを前提にしています。
D2009以降だと確実にコケます。
2進数 -> SJIS変換は途中に余計な文字があるとコケます。
(スペース等がある場合は事前にStringReplace等で取り除いてください)
では私はUnicode対応という事で、守備範囲はD6-D2010です。
こういうの見るとムラムラするんですよね。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//文字列を二進数文字列に--------------------------------------------------------
function ByteToStr(b:Byte):Char; begin
if b=0 then Result := '0' else Result := '1';
end;
function WordToBinStr(w:Word; b:Byte):WideString;
var i: Integer;
begin
SetLength(Result,b);
for i := 1 to b do
Result[i] := ByteToStr(Byte((w shr (b-i)) and $1));
end;
function WideCharToBinStr(wc:WideChar):WideString;
begin //WideCharは16bit = UNICODE
Result := WordToBinStr(Word(wc),SizeOf(wc)*8);
end;
function AnsiCharToBinStr(ac:AnsiChar):WideString;
begin //AnsiCharは8bit = Shift-JIS
Result := WordToBinStr(Word(ac),SizeOf(ac)*8);
end;
function WideStringToBinStr(wStr:WideString):WideString;
var i:Integer;
begin
for i := 1 to Length(wStr) do
Result := Result + WideCharToBinStr(wStr[i]);
end;
function AnsiStringToBinStr(aStr:AnsiString):WideString;
var i:Integer;
begin
for i := 1 to Length(aStr) do
Result := Result + AnsiCharToBinStr(aStr[i]);
end;
//二進数文字列を文字列に--------------------------------------------------------
function BinAnsiCharToWord(var bChar:AnsiChar):Word; begin
if bChar='1' then Result := 1 else Result := 0;
end;
function BinWideCharToWord(var bChar:WideChar):Word; begin
if bChar='1' then Result := 1 else Result := 0;
end;
function BinChar8ToChar(var ptChar:PAnsiChar):AnsiChar;
var
bSize : Byte;
i: Integer;
w: Word;
begin
w := 0;
bSize := SizeOf(AnsiChar)*8;
for i := 0 to bSize - 1 do
begin
w := (w Shl 1) or BinAnsiCharToWord(ptChar^);
inc(ptChar);
end;
Result := AnsiChar(w);
end;
function BinChar16ToChar(var ptChar:PWideChar):WideChar;
var
bSize : Byte;
i: Integer;
w: Word;
begin
w := 0;
bSize := SizeOf(WideChar)*8;
for i := 0 to bSize - 1 do
begin
w := (w Shl 1) or BinWideCharToWord(Char(ptChar^));
inc(ptChar);
end;
Result := WideChar(w);
end;
function Bin8StrToString(str:AnsiString):AnsiString;
var
ptChar:PAnsiChar;
begin
ptChar := @str[1];
repeat
Result := Result + BinChar8ToChar(ptChar);
until ptChar^=Char(0);
end;
function Bin16StrToString(str:WideString):WideString;
var
ptChar:PWideChar;
begin
ptChar := @str[1];
repeat
Result := Result + BinChar16ToChar(ptChar);
until ptChar^=Char(0);
end;
//------------------------------------------------------------------------------
//汎用関数
//Shift-JIS -> 2進数文字列
function ShiftJISToBinStr(str:string):string;begin
Result := AnsiStringToBinStr(str);
end;
//2進数文字列 -> Shift-JIS
function BinStrToShiftJIS(str:string):string;begin
Result := Bin8StrToString(str);
end;
//Unicode -> 2進数文字列
function UnicodeToBinStr(str:string):string;begin
Result := WideStringToBinStr(str);
end;
//2進数文字列 -> Unicode
function BinStrToUnicode(str:string):string;begin
Result := Bin16StrToString(str);
end;
//------------------------------------------------------------------------------
//用例
procedure TForm1.Button1Click(Sender: TObject);
begin
//Shift-JIS -> 2進数文字列
Edit2.Text := ShiftJISToBinStr(Edit1.Text);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//2進数文字列 -> Shift-JIS
Edit1.Text := BinStrToShiftJIS(Edit2.Text);
end;
end.
ご覧の通り最適化の余地はふんだんにあります、
可読性を重視しました。
こんにちは。
2進数 -> SJISを修正しました。
Mathユニットが不要になります。
function BinToStr(S: String): String;
var
i: Integer;
Buf: Byte;
begin
//2進数 -> SJIS
Result := '';
Buf := 0;
if Length(S) mod 8 = 0 then
begin
for i := 1 to Length(S) do
begin
if i mod 8 = 1 then Buf := 0;
if S[i] = #$31 then
begin
if i mod 8 = 0 then
begin
Buf := Buf + 1;
end
else
begin
Buf := Buf + 1 shl (8 - (i mod 8));
end;
end;
if i mod 8 = 0 then Result := Result + AnsiChar(Buf);
end;
end;
end;
ありがとうございます。
ベテランの方々のおかげで大変、充実した資料を得ることができました。
と、同時にすごく勉強になりました。
一発で変換できる関数まで示してくれたので大変たすかります。
重ねてありがとうございます。
解決の入れ忘れです…。
ツイート | ![]() |