電話番号は国内の固定電話番号は10ケタ、携帯電話の電話番号は11ケタと定められています。しかしながら表記は慣例というのみで明確な定義がありません。***-****-****や***-***-****や(****)**-****などはよく見ます。これらや区切りなしに対応していれば大体カバーできますが、やっかいなのが企業等の広告用電話番号です。お客さんに覚えてもらうために彼らは語呂合わせなどで電話番号を自由に区切って表記します。こういった番号が対象に含まれる電話番号認識が必要となった場合、一つ一つのケースに対応はとてもしてられません。慣例で表記される()-を無視して仕様中にある数の数を数える正規表現で電話番号を認識しましょう。?によるあってもなくてもいい、が有効です。
雑なパターン:(?:\d[\(\)-]?){10,11}
いくらか丁寧なパターン:\((?:\d\)?-?\(?){10,11}
そういえば WPA2 にも脆弱性がありましたね。Wi-Fi 業界では WPA3 という規格が決定した様です。
インターネットの世の中では、常に新しいソフトウェアへバージョンアップし、常に機器へ買い替えをしつづけなければ、古い機器のままインターネットへ接続しておくとあっという間に攻撃されて乗っ取られ、情報を取られたりします。
キリがないですがインターネットを使う以上はやらなければならない。
今回の WPA2 から WPA3 への対応は、ファームウェアバージョンアップで対応できる部分なのだろうか?
久しぶりのAndroidネタです。
今回は、端末が横向きになった場合でも、アプリの画面を縦方向に固定する方法について。
今回は、こちらのサイトを参考にさせていただきました。
Android縦画面固定 – Qiita
https://qiita.com/yasumodev/items/44f7fd84a58b709a0349
実装方法ですが、2つ方法があり、私が実装したのが、AndroidManifest.xml で指定する方法です。
縦方向で固定したいページのアクティビティに対して、下記を指定します。
android:screenOrientation="portrait"
具体的には、下記のようになります。
<activity android:name=".Main.MainActivity" android:screenOrientation="portrait" android:label="@string/app_name"/>
3行目に、縦方向で固定する指定を追加しています。
なお、横固定にしたい場合は、値を「portrait」から「landscape」に変更します。
次に、Activity で指定する方法ですが、こちらは onCreate の中に下記を記入します。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
こちらの方法で横方向で固定したい場合は、引数に ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE を指定します。
以上、アプリの画面の向きを固定する方法でした。
iOS だと、チェックボックスの ON/OFF だけで済むので、Android は少しだけ面倒ですね。
また、アクティビティごとでの指定なので、常に縦固定の場合は、すべてのアクティビティに縦固定の指定をしなければ習いので、指定抜けにご注意ください。
今回、盛大にハマったので記事にします。
詳細はいろいろな事情があって公開できないので、それっぽいコードで説明します。
いま、PHPを使ったWebアプリを開発しているのですが、このアプリはいろいろな事情からCookieを多用する設計になっています。
そしてこのCookieは基本的にPHP側(サーバーサイド)で書き込みを行うようにしています。PHPで書いた方が処理が簡単だったからです。
フレームワークとしてFuelPHPを使用しているので、下記の関数でCookieの操作ができます。
//Cookieの設定 Cookie::set(クッキーのキー, クッキーに格納する値, 有効期限, cookieを有効にするWebページのパス, cookieを有効にするドメイン, $secure = セキュアな接続の時のみ cookie を送信するか否か。, http経由での接続でのみ有効にするか否か); //Cookieの呼び出し Cookie::get(クッキーのキー, クッキーが取得できなかった時に返す値);
詳しくはこちらを参照してください。
Cookie クラス – FuelPHP 日本語マニュアル
で、例えば下記のようなコードを書いたとします。
$a="hoge" $result = Cookie::set("testkey",$a); //Cookieの送信に成功すればtrueを返す。 $b = Cookie::get("testkey",""); //書き込んだCookieを取得。 echo $result; var_dump($a); //① var_dump($b); //②
としたときに、$resultが”true”になっていれば、①と②の出力結果は同一のものになる、のが期待する動作なのですが、場合によって、②の時点での$bの値が”hoge”ではなく””になってしまうという事態が今回発生しました。
そんな馬鹿なと何度も確認したり、Cookie::setする前に対象のキーを削除したりいろいろ試したのですが、解決せず。
ここでふと、Google Chromeに、自分が保持しているクッキーの一覧が表示できる機能があったことを思い出し、こちら側でも確認してみました。
調査したいページを開いた状態でChromeの開発者ツール内のApplicationタブを開き、左側カラムの
Storage->Cookies->対象のサイトのURL
と辿っていくと、そのURLで保存されているCookieの一覧を見ることができます。
PHPがわの表示といっしょに、こちらの値の変化も確認していたところ、ブラウザ側で見たCookie”testkey”の値にはちゃんと期待した値の”hoge”という文字列が見えていました。
サーバーサイドからブラウザにCookieを渡す場合、実際にはHTTPのレスポンスヘッダに値を入れてブラウザに渡しています。
ブラウザからWebサーバーに対して接続した際に、基本的に応答が返ってくるまでに少し時間がかかります。
よくよく考えれば、サーバーに対しての通信で多少の遅延が発生するのなら、ブラウザへ値を保存する際に遅延が発生しても不思議ではないですよね。
今回はこの遅延が原因で、サーバーサイドで値がうまく取れなかったのではないか、と結論付けました。
…ということで、Cookieの値を保存・取得する際は、多少遅延が発生する可能性があるのでCookieを扱う際は注意が必要かも…というお話でした(;´∀`)
Wi-Fiは物理的な接続である有線LANと違い、電波が届く範囲内であればどこにいても接続が可能です。
そのため、物理的なケーブルであれば、不正につないでいる人を見つけることは大抵は難しいことではありませんが、無線であるWi-Fiの場合は電波が届けば接続出来てしまうので、誰かが不正に接続していても気づかないことがあります。
そういった場合を防ぐために、Wi-Fiには”パスワードがわかる人しか繋げられない”ようにする機能があります。
この機能、つまりWi-Fiの認証と暗号化の機能はいくつか規格があるのですが、いままで破られにくいとされていた”WPA2″が主流として使われていました。
ところがこのWPA2の認証を突破できてしまう”KRACKs”という攻撃方法が発見され、その堅牢性は崩れることになりました。
WPA2の脆弱性「パッチで対応可能」 Wi-Fi標準化団体が見解 – ITMedia
WPA2は業界共通の”標準規格”のため、簡単にアップデートすることは難しく、当面はパッチで対応する形でしのいていました。
そして今回、WPA2のアップデート版であるWPA3がついに策定されました。
新しいWi-Fiセキュリティ規格「WPA3」登場 – ITMedia
WPA3は、WPA2との互換性を維持しつつもKRACKsなどへの対策もされているとのこと。
WPA3では、WPA2デバイスとの相互運用性を維持しながらPMF(Protected Management Frames:管理フレーム保護)を必須とした。また鍵確立手法を従来のPSK(Pre-Shared Key:事前共有鍵)から新しいSAE(Simultaneous Authentication of Equals:同等性同時認証)に変更。ハンドシェイクの手順や認証の再試行回数を変更して各種攻撃への耐性を上げた。
今後発売される機器にはWPA3が搭載されることになりそうです。
また、ファームウェアアップデートが可能な機種でも、もしかすると利用可能になるかもしれません。
今後の動きに注目していきたいですね。
Twitter がログイン時の認証として、物理的な USB キーの認証に対応をしたようです。
Starting today, you can use a security key for login verification when you sign in to https://t.co/I6k1ntZlAv.https://t.co/Cu3PUyBsxz
— Twitter Safety (@TwitterSafety) 2018年6月26日
Twitter Safety(@TwitterSafety)さん – Twitter
Google 認証アプリはやめて、最近は IIJ ワンタイム生成アプリを使うようにしているので、機種変更したときでも以外とスムーズに移行はできているけど、そろそろ、指なUSBキー、YubiKeyも使い始めようかな。
USBだけじゃなくてNFC 対応品が良いとか考えると、結構高いんですよね。
絵が描けないので、Webデザイン中に毎回困るのがアイコン素材なのですが…数年前からかなりお世話になっているサイトがこちら。
「icooon-mono」という、フリーのアイコン素材のサイトです。
掲載しているアイコン数は何と6000以上!
また、タイトルにも書きましたが、商用利用も可能なのでかなり助かっています。
アイコンの詳細ページはこちら。
見てわかるように、アイコンのサイズが選べ、色も変えることができます。
また、ダウンロードするファイル形式も、PNG、JPG、SVG から選ぶことができます。
…まあ、たいてい選ぶのはPNGですけど。
オーソドックスな物から、一体どこで使うんだ?と思うような物まで、かなりの種類を取り揃えているので、きっとぴったりなアイコンが見つかるはず。
が、いかんせん量が多いので、最初は探すのだけでも一苦労かもしれません
時間があるときに、さらっと眺めてみるのもおすすめです。
ソースコードは早く理解されるコードであることが要求されます。早く理解されるためには、書かれている文字が何なのか読み取られるという方法があります。同じ動作を関数化することはよく使われる手法です。
function natcmp_name($a, $b) {
if (empty($a['nickname']) || $a['nickname'] == "") {
$a['nickname'] = $a['fullname'];
}
if (empty($b['nickname']) || $b['nickname'] == "") {
$b['nickname'] = $b['fullname'];
}
}
これは連想配列aと連想配列bを比較する関数です。比較の方法はニックネームの自然な辞書順の比較、もしニックネームがなければ代わりにフルネームを使う、です。この関数はabならば>0を返します。自然な辞書順というのは主に数字に関連した部分です。単純な辞書順では一文字ずつ文字を読み取り、違いが出た時点で順序を決定します。この単純な辞書順において’1abc’という文字列は’10abc’という文字列よりも後に並びます。これは2文字目のaと0の比較で0の方が辞書順で前に来るのが適当であるためです。自然な辞書順において’1abc’という文字列は’10abc’という文字列よりも後に並びます。
この関数を用いてある3人の名前の並び順を決定する。コードを書くと次の様になります。
function natcmp_name($a, $b) {
if (empty($a['nickname']) || $a['nickname'] == "") {
$a['nickname'] = $a['fullname'];
}
if (empty($b['nickname']) || $b['nickname'] == "") {
$b['nickname'] = $b['fullname'];
}
strnatcmp($a["nickname"], $b["nickname"]);
}
natcmp_name($person[1],$parson[2]);
natcmp_name($person[2],$parson[3]);
natcmp_name($person[3],$parson[1]);
3回の比較が12行程度で記述できました。これを関数抜きで記述した場合、次のようになります
if (empty($person[1]['nickname']) || $person[1]['nickname'] == "") {
$person[1]['nickname'] = $person[1]['fullname'];
}
if (empty($person[2]['nickname']) || $person[2]['nickname'] == "") {
$person[2]['nickname'] = $person[2]['fullname'];
}
strnatcmp($person[1]["nickname"], $person[2]["nickname"]);
if (empty($person[2]['nickname']) || $person[2]['nickname'] == "") {
$person[2]['nickname'] = $person[2]['fullname'];
}
if (empty($person[3]['nickname']) || $person[3]['nickname'] == "") {
$person[3]['nickname'] = $person[3]['fullname'];
}
strnatcmp($person[2]["nickname"], $person[3]["nickname"]);
if (empty($person[3]['nickname']) || $person[3]['nickname'] == "") {
$person[3]['nickname'] = $person[3]['fullname'];
}
if (empty($person[1]['nickname']) || $person[1]['nickname'] == "") {
$person[1]['nickname'] = $person[1]['fullname'];
}
strnatcmp($person[3]["nickname"], $person[1]["nickname"]);
21行であり、比較回数が増えればもっともっと増えます。これに目を通すのは前の例より時間がかかります。さらに置換ミスやタイプミスによる想定外の動作に気づきにくいという問題もあります。
もっとも、一番読むのが早いのは何も書かれていないコードです。上に並べたコードは比較をしましたが比較から何も返ってきません、データを参照して、操作しているだけです。最後のコードに至ってはデータを上書きで壊すバグの元ですらあります。再利用の可能性のある場合でもコメントアウト、再利用の可能性のない場合は完全に消去。読む必要のある部分は0行になります。
(?:)は(?:)で括られたグループは後方参照されないという記号です。後方参照は便利ですが、()もそれ以上に便利で多用しがちです。()が増えるとどこに何が格納されるかわかりにくくなりとても面倒です。(?:)ですっきりする例を挙げます。
<([a-z])(?:(\s[^>]+)?)>(.*)<\/>
HTMLやXMLの様なタグに使えそうな正規表現です。使えそうというのは、この表現は記事を書いている時の思い付きであり、私自身使ってないからです。.*はバグの温床です。これを(?:)抜きで状態遷移図っぽく可視化すると
(?:)を使って可視化すると
となります。前者のgroup2はいらない感じがしますが、後者では見事に消えています。
今回も、昨日に引き続き MySQL について。
タイトルにある通り、テーブルのデータをコピーして別のテーブルにデータを挿入する方法です。
使用頻度はあまり高くないかな?
今回参考にさせていただいたサイトはこちらから。
表をSELECTして別の表へINSERTする(INSERT ~ SELECT)- SQL Server – Priject Group
https://www.projectgroup.info/tips/SQLServer/SQL/SQL000004.html
なお参考として、記事の下の方に、同じことを Oracle Database で行う方法が書かれたページへのリンクもあります。
で、SQL文はこちら。
INSERT INTO [データ挿入先テーブル名] SELECT * FROM [コピー元テーブル名];
こちらは全カラム&全件をコピーする方法です。
もちろん、SELECT に WHERE をしてして、任意の条件に一致するデータのみを挿入することもできます。
なお、このSQL文はコピー元テーブルとコピー先テーブルの構造が一致していないと失敗するので、注意が必要です。
ですが、下記のように取得するカラムも指定すれば、定義の異なるテーブルにも挿入できます。
INSERT INTO [コピー先テーブル]([カラム1], [カラム2]) SELECT [カラム1], [カラム2] FROM [コピー元テーブル];
なお、カラムを指定するときは、順番にも気を付けてください。
以上、テーブルのデータをコピーして、別のテーブルに挿入する方法でした。
INSERT と SELECT が同時に使用されているので、一見難しそうに見えますが、落ち着いてみてみればかなり簡単ですね。
なお、実際に実行する機会があるかどうかは別として、同じテーブルにコピーしたデータを挿入することもできたので、テストデータとかを量産したいときとかに便利そうですね。