2ちゃんねる準拠トリップにての全角文字 - PHPプロ!Q&A掲示板

1166

  • 0P

2ちゃんねる準拠トリップにての全角文字

質問日時 / 2008年5月11日 21:07    回答数 / 12件

Questioner:  atsu_7420  このエントリーをはてなブックマークに追加 

キーワード / 2ちゃんねる    トリップ   

トリップ機能を設けたいと思い、各種サイトを参考にしながら、2ちゃんねる型のトリップを作るコードを考え出しました。以下です。
ここではトリップ「#○○○~」が含まれる文字列を $name とします。
  1. $name = str_replace('◆','◇',$name);
  2. $trips = strpos($name, "#");
  3. if ($trips !== false){
  4. $honn = substr($name, 0,$trips);
  5. $tripn = substr($name,$trips + 1);
  6. $salt = substr($name,$trips + 2,$trips + 3);
  7. $trip = crypt($tripn,$salt);
  8. $trip = substr($trip,-10);
  9. $name = $honn . '◆' . $trip;
  10. }
という風になりました。
#Test といったトリップも本家2ちゃんねる通りになります。
ですが、
#テスト といった全角文字を含むトリップがうまく変換されません。
というのもエラーは出ないのですが、正しいトリップと違った文字列に変換されてしまうのです。
なぜでしょうか。どうすれば全角も対応させることができるようになるのでしょうか。
よろしくお願いします。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01TorrySegall真っ先に疑うべきは『文字コードの相違』かと思います
┃┗A01-1atsu_7420なるほど。一理あると思います。 >>CODE $name = st
┗A02win_phpトリップ機能は使ったことが無いので仕様はわからない
 ┗A02-1atsu_7420substr()をすべてmb_substr()に置き換えましたがうま
  ┗A02-1-1win_phpmb_substrに置き換えたとして、 $honn = mb_substr
   ┗A02-1-1-1atsu_7420>>CODE $honn = mb_substr($name, 0,$trips,"Shift_J
    ┗A02-1-1-1-1win_php時間が空いたのでトリップ機能を理解したうえで試して
     ┗A02-1-1-1-1-1atsu_7420それでは意味がないのです。。。 準拠していませんの
      ┗A02-1-1-1-1-1-1win_phpこの行は $salt =~ tr/:;<=>?@[\\]^_`/ABCDEFGabcd
       ┗A02-1-1-1-1-1-1-1atsu_7420やってみましたが、、、 #テスト は、 ◆SQ2Wyjdi7M
        ┗A02-1-1-1-1-1-1-1-1win_phpさきほどは時間がなく、$salt =~ s/[^\.-z]/\./go;
         ┗A02-1-1-1-1-1-1-1-1-1atsu_7420ありがとうございます! おかげさまで無事「完全準拠

回答一覧

並び替え:

A01
answererTorrySegall [5月12日 02:52]

真っ先に疑うべきは『文字コードの相違』かと思います。

この意見に回答する

ツリーへ TOPへ

A01-1
replyeratsu_7420 [5月12日 16:48]

なるほど。一理あると思います。
  1. $name = str_replace('◆','◇',$name);
  2. $trips = strpos($name, "#");
  3. if ($trips !== false){
  4. $honn = substr($name, 0,$trips);
  5. $tripn = substr($name,$trips + 1);
  6. $tripn = mb_convert_encoding($tripn, "Shift_JIS", "auto");
  7. $salt = substr($name,$trips + 2,$trips + 3);
  8. $salt = mb_convert_encoding($salt, "Shift_JIS", "auto");
  9. $trip = crypt($tripn,$salt);
  10. $trip = substr($trip,-10);
  11. $name = $honn . '◆' . $trip;
  12. }
ですが、上記のように書き換えてみましても、うまくいきません。
当方はShift_JIS、2chの方もShift_JISのようですが。

この意見に回答する

ツリーへ TOPへ

A02
answererwin_php [5月13日 00:15]

トリップ機能は使ったことが無いので仕様はわからないのですが、
多分、以下の理由かと思います。


半角文字と全角文字ではバイト数が違います。

Shift_jis環境なら、半角英数文字は1バイトですが、
全角は2バイトでしょう。


  1. <?php
  2.  
  3. // バイト数の比較
  4. print strlen('テスト').'<br>';
  5.  
  6. // マルチバイト関数が利用できるサーバーであれば、
  7. print mb_strlen('テスト');
  8.  
  9.  
  10. ?>



substr()ではなく、

mb_substr() を利用すれば全角文字も1文字としてカウントできるかと思います。


詳しくはマルチバイト関数について調べてみてください。

この意見に回答する

ツリーへ TOPへ

A02-1
replyeratsu_7420 [5月16日 22:30]

substr()をすべてmb_substr()に置き換えましたがうまく行きません・・・。

この意見に回答する

ツリーへ TOPへ

A02-1-1
replyerwin_php [5月17日 03:37]

mb_substrに置き換えたとして、

$honn = mb_substr($name, 0,$trips,shift_jis); 
$tripn = mb_substr($name,$trips + 1,shift_jis); 
$salt = mb_substr($name,$trips + 2,$trips + 3,shift_jis); 

この3つで

$tripn = mb_substr($name,$trips + 1,shift_jis);

だけ違うのはなぜ??

mb_substr ( string $str , int $start , int $length , string $encoding )

の型になっていない。かなぁ??

この意見に回答する

ツリーへ TOPへ

A02-1-1-1
replyeratsu_7420 [5月18日 13:14]

  1. $honn = mb_substr($name, 0,$trips,"Shift_JIS"); 
  2. $tripn = mb_substr($name,$trips + 1,10,"Shift_JIS"); 
  3. $salt = mb_substr($name,$trips + 2,$trips + 3,shift_jis);
と思います。
書式は
mb_substr ( string $str , int $start [, int $length , string $encoding] )
で、文字列の長さと文字コードは省略可なので。
とりあえずここでは文字列長を10にしました。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1
replyerwin_php [5月19日 22:38]

時間が空いたのでトリップ機能を理解したうえで試してみました。

  1. <?php
  2. $name'名前#テスト';
  3. $name = str_replace('','',$name)
  4. $trips = mb_strpos($name"#")
  5. if ($trips !== false){ 
  6. $honn = mb_substr($name0,$trips)
  7. $tripkey = mb_substr($name,$trips + 1,10)
  8. $salt = mb_substr($name,$trips + 2,$trips + 3)
  9. $trip = crypt($tripkey,$salt)
  10. $trip = mb_substr($trip,-10)
  11. $name = $honn . '' . $trip
  12. }
  13.  
  14. echo $name;
  15. ?>

名前◆TyQkuBS.4Y  と表示されました。

$name= '◆TyQkuBS.4Y';

だと、

名前◇TyQkuBS.4Y  になります。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1
replyeratsu_7420 [5月30日 18:32]

それでは意味がないのです。。。
準拠していませんので。。。

とりあえずPerlでは

$tripkey = "#istrip";  # パスワードとする文字列(# 付き)
$tripkey = substr($tripkey,1);
$salt = substr($tripkey.'H.',1,2);
$salt =~ s/[^\.-z]/\./go;
$salt =~ tr/:;<=>?@[\\]^_`/ABCDEFGabcdef/;
$trip = crypt($tripkey,$salt);
$trip = substr($trip,-10);
$trip = '◆'.$trip;
print "$trip";

となっているようですが。
これを移植できませんかね?

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1
replyerwin_php [5月30日 22:47] (最終編集:5月30日 23:23)

この行は

$salt =~ tr/:;<=>?@[\\]^_`/ABCDEFGabcdef/;

tr/検索文字/置換文字/ という演算子です。
(文字列でなく文字です)

PHP なら、str_replace()で置換できますね。


$salt = str_replace("置換する文字, 置換文字, $salt);

:はA , ;はB という具合に置換ですね。

  1. $patterns = ":;<=>?@[\\]^_`";
  2. $match = "ABCDEFGabcdef";
  3. for($i = 0; $i <= 13 - 1; $i++){
  4. $salt = str_replace($patterns[$i], $match[$i], $salt);
  5. }

こんな感じかな

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1
replyeratsu_7420 [5月31日 11:29]

やってみましたが、、、
#テスト
は、
◆SQ2Wyjdi7M
になるはずなのですが。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-1 満足
replyerwin_php [6月1日 00:36] (最終編集:6月1日 00:43)

さきほどは時間がなく、$salt =~ s/[^\.-z]/\./go;

の部分は説明してなかったです。


  1. <?php
  2. $tripkey = htmlspecialchars("テスト",ENT_QUOTES);
  3. $salt = htmlspecialchars("テスト",ENT_QUOTES);
  4. $salt = substr($tripkey.'H.',1,2);
  5. // $salt =~ s/[^\.-z]/\./go;にあたる箇所
  6. $pattern = '/[\x00-\x20\x7B-\xFF]/';
  7. $salt = preg_replace($pattern,".",$salt);
  8.  
  9. $patterns = ":;<=>?@[\\]^_`";
  10. $mach = "ABCDEFGabcdef";
  11. for($i = 0$i <= 13 - 1$i++){
  12. $salt = str_replace($patterns[$i]$mach[$i]$salt);
  13. }
  14.  
  15. $trip = crypt($tripkey,$salt);
  16.  
  17. $trip = substr($trip,-10);
  18. $trip = ''.$trip;
  19. print "$trip";
  20.  
  21. ?>


これで、◆SQ2Wyjdi7M なりました。

あと改造してもらえれば。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-1-1
replyeratsu_7420 [6月6日 22:16] (最終編集:7月6日 12:28)

ありがとうございます!
おかげさまで無事「完全準拠」といえるようになりました!
わざわざ本当に感謝しています。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
マジッククォートとmysql_real_escape_string
 このエントリーをはてなブックマークに追加 
A
magic_quotes_gpcでは、SQLインジェクション対処は十分できません。主な理由として、以下が上げられます。 ・magic_quotes_gpcは文字コードを考慮しないで処理するので、Shift_JISを使っている場合、SQLインジェ...

>>続きを読む

SQLインジェクション対策は時と場合で使う関数が変わります。その時にあったものを使いましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)