星期五, 7月 28, 2017

2017 年京阪神奈六日自由行散策 - 第一天

關西空港

安小迪和公主大人終於到關西空港(雀躍),


趁著現在時間還早,

到了日本第一件重要的事情,

就是要去把這六天行程的買票好,

因為安小迪與公主大人是第一航廈入境,

所以就先到關西觀光情報中心,

購買大阪周遊券和神戶 CITY LOOP,


接著,理所當然就是到 JR Ticket Office 購票囉!


因為我們有線上預約(由此去),

所以就可以省下填寫資料的時間囉!



嵐山的票票是一起買的,


看到這些票票都到手以後,

安小迪與公主大人終於可以放心地搭特快列車 HARUKA 號到我們住宿的地方嚕!


小知識:關西國際機場是全世界第一座百分之百填海造陸而成的人工島機場,它同時也是一座海上機場。1960年代,關西地方的航空需求逐漸擴大,而且大阪周邊用地吃緊,因次日本政府決定以填海造地修建機場,經過5年的填海工程,用了1.8億立方公尺的土方,在原先水深達17至18公尺的大海裡填出了5.11平方公里的機場用地。(摘自:維基百科)


四條河原町

終於到四條河原町了~

這裡不愧是京都最熱鬧的地區,

先讓我們放個行李先,

接著就開始我們快樂行程啦~XDD



小知識:四條河原町是四條通和河原町通兩條道路的十字路口,被包含在日本三大祭之一的祇園祭的山鉾巡行的路線之中,在該路口左轉的「辻回し」也是祇園祭的主要看點,也是京都市內最繁華的地區。(摘自:維基百科)


清水寺

今年的清水寺雖然在整修中,


但是還是很漂亮的,

只是人不是普通的多,

天氣不是普通的熱,

所以安小迪與公主大人都盡量找涼涼的地方望望看看囉!


小知識:清水寺與北山鹿苑寺(金閣寺)、嵐山天龍寺等同為京都境內最著名的名勝古蹟,也是西國三十三箇所(在關西地區參拜33所觀音廟的巡訪活動)中第16所寺廟。自平安時代以來,就經常出現於日本文學作品當中。1994年,清水寺以身為古都京都的文化財之一部分,列名至世界文化遺產中。(摘自:維基百科)


三年坂

據說在這裡跌倒會倒楣三年,


所以安小迪和公主大人在這裡都非常的注意,


畢竟不希望真的倒楣三年的說~XDD

小知識:產寧坂又稱三年坂,據說是豐城秀吉妻子寧寧,為了去清水寺的子安塔祈求生產順利,在經過連接清水寺的坂道時,起名為產寧坂。又有一說是三年坂因建於大同三年而得名。(摘自:京の坂みち)


二年坂

走在坂道上,


兩側的日式建築,

結合了咖啡與商家,

卻完全不突兀,

彷彿穿梭於一、二百年前的日式街道般。


原本想進去二年坂的星巴克,

體驗一下在塌塌米上喝杯咖啡感覺,

沒想到下午突然之間下了大雨,

整個星巴克客滿,不提供服務,

只能留待下次再來囉!


小知識:二寧坂又稱二年坂,因為是產寧坂(又稱三年坂)前面的坂道,所以這條路被稱為二寧坂。另一說是大同二年(西曆 807 年)修理坂道的時候起的這個名字。傳說「在二寧坂摔倒話,兩年內會死亡」的說法,其實可以理解為「小心石坂道」的意思。(摘自:京の坂みち)


八坂神社/祇園祭

安小迪與公主大人這一次來京都,

遇到每年七月一日到七月三十一日的祇園祭,

安小迪第一次遇到日本的祭典,

心情真是非常地興奮啊!



很幸運的是~今天的祇園祭的日程「神用水清祓式」,


在逛完花見小路後,

就到四条大橋體驗一下日本的祭典。


小知識:日本三大祭之一的「祇園祭」是由京都的八坂神社舉辦的,是一個具有一千多年歷史的節慶活動。以前,八坂神社的名字是「祇園神社」,所以被稱為祇園祭。(摘自:日本政府觀光局)


花見小路

下午雖然下了大雨,

還好大概五點雨就漸漸停了

黃昏時分,

與花見小路古色古香的街道房屋,

安小迪、公主大人與遊客們要是都換上和服,

都會覺得自己變身為古代的日本人了~XDD
(迷之音:說好的藝妓怎麼一個都沒有出現啊?!)


小知識:花見小路通是日本京都市的一條南北向街道,北到三條通,南到安井北門通,是經過祇園中心區的主要街道。(摘自:京都觀光 Navi)


一蘭拉麵

這就是公主大人心心念念的一蘭拉麵,

每次到日本至少都要吃一次,

要不然公主大人就覺得好像沒有到日本一樣~嘖嘖嘖~



-
路線:

第一段:
(交通約 3 hrs 40 mins,停留時間 1+ hr [08:20~09:40])
桃園國際機場 > 搭飛機 > 關西國際機場

第一段:
(交通約 1~2 hrs [班次 09:46],停留時間 1- hr [11:00~12:30])
關西國際機場 > HARUKA > 京都駅 > 步行 > 京都駅(Shiokoji Takakura Bus Stop) >

市営205甲 > 四條河原町(Kawaramachi Sanjo Bus Stop) > 步行 > 京都格蘭小姐飯店

第二段:
(交通約 40 mins,停留時間 6+ hrs [13:40~19:00])
京都格蘭小姐飯店 > KYOTO LOOP > 清水寺 > 三年坂 > 二年坂 > 八坂神社 > 花見小路 > 四條河原町

任意門:


2017 年京阪六日自由行散策 - 第一天






2017 年京阪神奈六日自由行散策 - 出發篇

繼上次由公主大人安排的東京五日遊後,

等待了一年,

終於又要跟公主大人出國玩嚕~

出遊前~裡所當然的要個行前規劃囉!

由於去年東京是由公主安排的,

所以呢~公主將今年的京阪六日交給安小迪安排,

安小迪非常的認真找了JR、地鐵、公車等路線,


好不容易排出了第一天的行程由此去

立馬被公主大人嫌棄(傷心)😢~

最後安小迪還是不負公主大人期望把行程排完了(攤手)~
(IMPORTANT: 安小迪絕對沒有故意亂排行程,好讓公主大人可接手,迷之音可以證明)

大致安排的行程如下:

第一天:

關西空港→四條河原町→清水寺→三年坂→二年坂→八坂神社/祇園祭→花見小路→覓食
(迷之音:這行程...怎麼這麼眼熟啊...)

第二天:

四條河原町→嵐山→金閣寺→錦市場→河原町(貓頭鷹館)→燒肉

第三天:

四條河原町→奈良公園→宇治(平等院)→伏見稻荷神社→京都車站→大阪(難波)

第四天:

大阪難波(大阪週遊卷)→帆船觀光船→大阪生活今昔館→天守閣→通天閣→道頓崛水上觀光船→日本橋

第五天:

大阪難波→北野異人館→生田神社→神戶港/神戶塔→摩耶山(掬星台)→梅田阪神百貨/Yodobashi→道頓崛/心齋橋

第六天:

大阪閒逛→臨空城Outlet→關西空港→桃園機場

終於要出發了~

由於今天機場捷運已經開始營運了,

所以安小迪今年就搭著機場捷運出發到桃園國際機場與公主大人會合了~


拖著曾經陪著公主大人征戰旅行可愛的行李箱~小紫~
(迷之音:小紫表示~他是被公主大人四處撞到瘀青的~XDD)


其實安小迪與公主大人的班機是凌晨 5 點,

所以我們現在是準備去機場睡覺的,

有了上次東京五日的紅眼班機經驗,

安小迪這次有了萬全地準備~


登.登.登.登~~~

看到沒~~充氣枕頭~~~

這次我應該可以睡得比較好點,

頭應該不會扭到了~XDD

到了桃園國際機場了,

安小迪的公主大人~安小迪來了(飛奔)~


這個時間的桃機似乎真的沒有什麼東西呢!

四處看看除了便利商店外,

沒有什麼可以覓食的~

但是,發現機場最厲害的是...


我家公主在機場美食街看韓劇啦!😄

經過了漫長的等待,

終於準備登機囉~日本我來了(雀躍)~
(迷之音:Nintendo Switch 安小迪要來把你帶回家囉~)


附帶一提,

現在的機場休息區除了提供充電等服務外,

環境也非常的舒適。


就讓安小迪與公主大人好好休息一下,

等等準備上飛機前往日本關西機場囉!


-
任意門:

2017 年京阪六日自由行散策 - 出發篇








星期三, 6月 07, 2017

公主大人意外的 LV Capucines 長夾開箱

終於要為這個 LV Capucines 長夾開箱了!

不過這個長夾的獲得,

真的是讓安小迪與公主大人又驚又喜啊!

所以安小迪只好來說一下小故事囉!
(迷之音:明明就自己愛說話~XDD)

很久之前公主大人買了一個桃紅色 LV 長夾,

用了一段時間後呢,

這個桃紅色的長夾邊緣的膠卻突然越變越軟、越變越黏,

弄髒弄醜公主大人好幾個心愛的小皮夾、零錢包、提包...
(迷之音:怎麼有種背椎發涼的港覺~抖~~)

但是公主大人又非常喜歡它,

捨不得丟,所以就將它封存,沒再使用它。

在今年的某天,

公主大人和安小迪去逛新光三越閒逛吹冷氣的時候,

看到了 LV 旗艦店,

讓公主大人突然想起了這個被封存已久桃紅色 LV 長夾

於是乎~

找了一天,帶著這個壞掉的長夾,

抱著能修就修的心情到了 LV 旗艦店,

在與專櫃小姐說明並查閱了電腦資料後,

專櫃小姐與我們說明公主大人當初買的這長夾,

在歐美因天候的關係是不會有醬的問題,

但是台灣天候比較潮濕,

有不少客戶反應這樣的狀況,

所以已經將那批貨的膠與貨全數做更換,

但是現在已經沒有那款長夾可以替換了!!

這時安小迪看到公主大人的眼睛泛著淚光,
(迷之音:這個公主大人絕對不會承認的~~~)

帶著失望的眼神~正準備離開~

專櫃小姐接著說,

會以當初停產的市價讓我們換購新的商品。

說時遲,那時快,

安小迪立馬看到公主大人突然眼睛閃閃發光~XDD

最後貼了些錢錢,選購了這個新長夾,

雖然打亂了公主原本想買 CHANEL 長夾的計畫,

也讓安小迪和公主大人覺得 LV 的服務真不一般,

給予高度的肯定。

拍個幾張開箱照,跟大家分享公主大人的喜悅~

當天公主大人有選擇要替長夾燙金,


所以是安小迪後來下班後,

去了一趟新光三越幫公主大人拿回來的。


在回來的路上,安小迪還深怕把長夾弄丟,

手抱握得緊緊的,

而且是以飛快的速度將長夾拿回家(抖~~)。


打開時感覺長夾的包裝非常簡單,

但是相當的有質感,

包裝長夾的布套,摸起來質地也非常好。


安小迪雖然不懂名牌包,

但是公主大人選的這個黑色長夾,

看起來真的是非常的有質感,而且很耐看。


說真的~沒想到燙金還真蠻好看的,

並不會讓人感到突兀,

而且整體上對長夾有加分的效果。


然後~裡面還是桃紅色的~XDD

就醬囉~

LV 雖然非常貴,但是經過這次的經驗,

深深覺得~這樣的售後服務真是沒有話說。


星期二, 5月 30, 2017

在 IIS 10 安裝 PHP Manager for IIS

安小迪在上一篇筆記中寫到,

如果各位有需求,

透過 Web Platform Installer 安裝程序安裝 ARR 2.5 和 URL Rewrite 2.0 時(由此去),

可以透過 Regedit.exe 修改 IIS 10 版本號的方式進行安裝,

但,這個部分在安裝 PHP Manager for IIS 時可能卻不管用,

怎麼個不管用法呢?!

因為既使 Web Platform Installer 安裝程序讓你看到安裝完成了!

在 IIS 首頁也依然看不到 PHP Manager 的圖標,

後來透過 Google 大神,

在網路上找到了 PHP Manager support IIS 8、IIS 8.5、IIS 10 的連結(由此去),

順利將 PHP Manager for IIS 裝上,

如下圖:


希望對遇到有相同問題的人有幫助喔~~


星期一, 4月 24, 2017

在 IIS 10 上安裝 Application Request Routing 2.5 & URL Rewrite 2.0


若各位有要在 IIS 10 安裝 ARR 2.5 或 URL Rewrite 2.0 的功能時,

應該會遇到安裝檔檢查 IIS 版本導致無法安裝的問題,

這時候僅需要使用 regedit.exe 修改如下機碼即可:

IIS 版本機碼位置
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters

設定機碼
MajorVersion 是 DWORD 值,它的值十進制是 10,把它改成 9;

然後使用 Web Platform Installer 安裝程序即可順利安裝上了!

記得裝完之後將機碼改回來,

這樣就能正常順利在 IIS 10 上使用 ARR 及 URL Rewrite 功能。

如下圖:


希望能在有新版本前,幫上有使用需求的人。

就醬~晚安囉~

星期六, 4月 08, 2017

SQL Server Management Studio 資料表設計模式顯示欄位描述

相信各位自以前設計資料表時,

都會有替資料表欄位的描述寫上註解說明的好習慣,

但是每次看欄位描述裡的註解說明時,

都要先選取該欄位,

然後在屬性位置查看欄位描述的註解說明,

非常的麻煩與不直覺。

以下方法使用 regedit.exe 修改機碼,

可以讓你在設計模式就可以直接編輯查看欄位描述。

首先,依據你 SSMS 的版本找到對應的機碼位置,

如下:

SQL Server 2008
HKEY_CURRENT_USER\Software\Microsoft\SQL Server Management Studio\11.0\DataProject

SQL Server 2014
HKEY_CURRENT_USER\Software\Microsoft\SQL Server Management Studio\12.0\DataProject

SQL Server 2016
HKEY_CURRENT_USER\Software\Microsoft\SQL Server Management Studio\13.0\DataProject

設定機碼
SSVPropViewColumnsSQL70 從 1,2,6; 改為 1,2,6,17;
SSVPropViewColumnsSQL80 從 1,2,6; 改為 1,2,6,17;

如下圖:



這裡提供其他屬性欄位代號,

讓各位可以依據自己的需求,

客製調整設計模式要顯示的欄位資料。

各個屬性欄位代號:
1    Column Name
2    Data Type
3    Length
4    Precision
5    Scale
6    Allow Nulls
7    Default Value
8    Identity
9    Identity Seed
10    Identity Increment
11    Row GUID
12    Nullable
13    Condensed Type
14    Not for Replication
15    Formula
16    Collation
17    Description

就醬囉~~

星期三, 12月 21, 2016

大有量長夾開箱(貓吉鞄製所)

聖誕節交換禮物時,

不小心讓公主大人遇見正在製作手工皮件的朋友,

說遲時,那時快,公主立馬開啟採購模式,

直接當場下單~(攤手~該來的始終跑不掉~XDD)

製作好後,朋友非常貼心,

拿了一個印了可愛貓吉的盒子裝著,


大家都那麼熟了!

下次可以省下來啊~XDD


這就讓我們來看看公主大人買了什麼吧!

一個長夾和一個小的名片/零錢包


長夾攤開整個容量非常大,


可以把整隻 iPhone 6 Plus 和護照放進去都沒有問題,


名片/零錢包的大小也剛剛好,


攤開後除了可以放名片外,還可以放上零錢,


如果出門一下下,不想帶著長夾,還可以塞個卡和幾張鈔票就可以出門了~

非常的樸素的設計,而且實用,
(看著公主大人心滿意足的表情,這次不用跪算盤了~XDD)

有興趣的朋友,也可以去貓吉鞄制所看看,也有提供客製服務喔~

星期四, 7月 21, 2016

ARTBOX 26 吋 PC 玫瑰金鏡面鋁框行李箱

奇怪~怎麼我房間又多了東西呢?!
(又來~每次打開箱文都要演一次,累不累啊~)

而且還蠻大一箱~


究竟是什麼東西呢?!


這莫非是上帝知道我準備出國旅遊了!所以送來的禮物?!


好吧~演不下去了~XDD

其實是很久沒有寫部落格了~

所以就補開一下去年去日本旅遊前,新買來給公主大人用的行李箱囉~

沒辦法!因為公主的行李箱實在是用太久了~
(其實是公主行李箱實在是太舊舊髒髒的,真心覺得...該換了...這算爆料嗎~XDD)

而且奴才小的實在捨不得公主大人這麼節儉~

所以呢~就擅自買了個公主大人喜歡的玫瑰金行李箱給公主大人囉!
(公主大人實在太明顯了~一直在看玫瑰金的大行李箱~時不時都跟我說好漂亮哦~嘖嘖嘖~)

讓我們來看看完整的行李箱吧~


說真的玫瑰金真的蠻好看的,而且26吋的大小,給公主用絕對不嫌小~
(事實證明,公主還是把它塞滿了~XDD)


行李箱裡面的空間個人是覺得非常大,


放入我的行李讓大家感受一下裡面實際的大小,

看來對我而言,五天四夜的日本行,這行李箱太大了些!


請不要不相信,這樣就是我全部的行李~是不是太大了~XDD


厲害的是~我們回國的時候他是滿的~XDD

這行李箱的多段式鋁合金拉把拉起來的樣子~


上側回彈把手還蠻好提拿行李箱的,

加上新買的吉卜力行李吊牌一起入鏡~XDD


TSA全球認證海關鎖不會很卡很難使用,

側邊的回彈把手也蠻好提拿的,


鋁框的密合對非常好,而且有一體成形的防撞護角,

當然是不希望撞到,但是每次提領行李的時候都會傷到,

幸好這個行李箱整個有包膜。


實際使用上非常滿意,

不過呢~過海關去拿行李的時候還是有傷到,

感恩外面那層保護的膠膜,

但是應該不堪再次受創,

所以回國後額外買了一個 Deseno 的透明防刮旅行箱套,

如果喜歡而且在意行李箱外觀的朋友,除了購買行李箱外,還是建議買個旅行箱套喔!
(因為爆公主大人的料,所以我現在要負荊請罪去了~QQ~~~~~)


星期五, 7月 08, 2016

TripleDES/AES(CBC/PKCS7) 在 .NET/Java/PHP/Delphi 加解密互通範例

加解密在不同程式語言中一直給程式設計師很多困擾,

尤其是 .NET 到其他程式語言,

所以寫這篇以 .NET 為基礎,

以 TripleDES/AES 加解密,Cipher Mode 使用 CBC,Padding Mode 使用 PKCS7,

提供 .NET/Java/PHP/Delphi 加解密程式範例:
(備註:因為我沒有 Delphi 環境,所以 Delphi 的範例是摘自朋友 kuraki5336 網誌)

.NET 範例 (TripleDES/DES/AES):
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace Sample
{
    /// <summary>
    /// 對稱式加密模式。
    /// </summary>
    public enum SymmetricMode
    {
        /// <summary>
        /// AES 加密演算法。
        /// </summary>
        AES,
        /// <summary>
        /// DES 加密演算法。
        /// </summary>
        DES,
        /// <summary>
        /// TripleDES 加密演算法。
        /// </summary>
        TripleDES
    }
    /// <summary>
    /// 對稱式加密類別(無法被繼承)。
    /// </summary>
    /// <remarks>本加解密類別是使用 UTF8 進行字串資料的轉換,當加密的資料是由 ASCII 或其他格式編碼,會造成資料無法正確解密。</remarks>
    public sealed class SymmetricCryptoUtility : IDisposable
    {
        /// <summary>
        /// 對稱式加密演算法物件。
        /// </summary>
        private readonly SymmetricAlgorithm Crypto = null;
        /// <summary>
        /// 演算法類型。
        /// </summary>
        private readonly SymmetricMode Mode;
        /// <summary>
        /// 對稱式加密類別建構式(無法被繼承)。
        /// </summary>
        /// <param name="algorithm">演算法類型。</param>
        public SymmetricCryptoUtility(SymmetricMode algorithm)
        {
            this.Mode = algorithm;

            switch (this.Mode)
            {
                case SymmetricMode.AES: this.Crypto = new AesCryptoServiceProvider(); break;
                case SymmetricMode.DES: this.Crypto = new DESCryptoServiceProvider(); break;
                case SymmetricMode.TripleDES: this.Crypto = new TripleDESCryptoServiceProvider(); break;
            }

            if (null == this.Crypto) throw new Exception();
        }
        /// <summary>
        /// 產生要用於該演算法的隨機初始化向量。
        /// </summary>
        /// <returns>向量字串。</returns>
        public string GenerateIV()
        {
            string szResult = String.Empty;

            this.Crypto.GenerateIV();

            szResult = Encoding.UTF8.GetString(this.Crypto.IV);

            return szResult;
        }
        /// <summary>
        /// 產生要用於演算法的隨機金鑰。
        /// </summary>
        /// <returns>金鑰字串。</returns>
        public string GenerateKey()
        {
            string szResult = String.Empty;

            this.Crypto.GenerateKey();

            szResult = Encoding.UTF8.GetString(this.Crypto.Key);

            return szResult;
        }
        /// <summary>
        /// 依據設定的演算法進行資料加密。
        /// </summary>
        /// <param name="originalString">原始未加密的字串。</param>
        /// <param name="key">金鑰字串</param>
        /// <param name="iv">向量字串</param>
        /// <returns>計算出來的加密位元組。</returns>
        public byte[] EncryptToBytes(string originalString, string key, string iv)
        {
            byte[] byResult = null;
            // Set Key and IV.
            this.Crypto.Key = Encoding.UTF8.GetBytes(key);
            this.Crypto.IV = Encoding.UTF8.GetBytes((this.Mode == SymmetricMode.AES ? iv : iv.Substring(0, 8)));
            // Encrypt a string to bytes.
            using (MemoryStream memoryStream = new MemoryStream())
            {
                ICryptoTransform cryptoTransform = null;

                switch (this.Mode)
                {
                    case SymmetricMode.AES: cryptoTransform = ((AesCryptoServiceProvider)this.Crypto).CreateEncryptor(); break;
                    case SymmetricMode.DES: cryptoTransform = ((DESCryptoServiceProvider)this.Crypto).CreateEncryptor(); break;
                    case SymmetricMode.TripleDES: cryptoTransform = ((TripleDESCryptoServiceProvider)this.Crypto).CreateEncryptor(); break;
                }

                using (CryptoStream encStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
                {
                    UTF8Encoding oUTF8 = new UTF8Encoding(false);

                    using (StreamWriter streamWriter = new StreamWriter(encStream, oUTF8))
                    {
                        // Write the originalValue to the stream.
                        streamWriter.Write(originalString);
                        // Close the StreamWriter.
                        streamWriter.Close();
                    }
                    // Close the CryptoStream.
                    encStream.Close();
                }
                // Get an array of bytes that represents the memory stream.
                byResult = memoryStream.ToArray();
                // Close the memory stream.
                memoryStream.Close();
            }
            // Return the encrypted string.
            return byResult;
        }
        /// <summary>
        /// 依據設定的演算法進行資料加密。
        /// </summary>
        /// <param name="originalString">原始未加密的字串。</param>
        /// <param name="key">金鑰字串。</param>
        /// <param name="iv">向量字串。</param>
        /// <returns>計算出來的加密字串。</returns>
        public string Encrypt(string originalString, string key, string iv)
        {
            string szResult = String.Empty;
            // Encrypt a string to bytes.
            byte[] byBuffer = this.EncryptToBytes(originalString, key, iv);
            // Convert to base 64 string.
            szResult = Convert.ToBase64String(byBuffer);
            // Return the encrypted string.
            return szResult;
        }
        /// <summary>
        /// 依據設定的演算法進行資料解密。
        /// </summary>
        /// <param name="encryptedBytes">被加密的位元組。</param>
        /// <param name="key">金鑰字串。</param>
        /// <param name="iv">向量字串。</param>
        /// <returns>原始的字串。</returns>
        public string DecryptFromBytes(byte[] encryptedBytes, string key, string iv)
        {
            string szResult = String.Empty;
            // Set Key and IV.
            this.Crypto.Key = Encoding.UTF8.GetBytes(key);
            this.Crypto.IV = Encoding.UTF8.GetBytes((this.Mode == SymmetricMode.AES ? iv : iv.Substring(0, 8)));
            // Create a memory stream to the passed buffer.
            using (MemoryStream memoryStream = new MemoryStream(encryptedBytes))
            {
                ICryptoTransform cryptoTransform = null;

                switch (this.Mode)
                {
                    case SymmetricMode.AES: cryptoTransform = ((AesCryptoServiceProvider)this.Crypto).CreateDecryptor(); break;
                    case SymmetricMode.DES: cryptoTransform = ((DESCryptoServiceProvider)this.Crypto).CreateDecryptor(); break;
                    case SymmetricMode.TripleDES: cryptoTransform = ((TripleDESCryptoServiceProvider)this.Crypto).CreateDecryptor(); break;
                }

                // Create a CryptoStream using the memory stream and the CSP DES key. 
                using (CryptoStream encStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
                {
                    UTF8Encoding oUTF8 = new UTF8Encoding(false);

                    // Create a StreamReader for reading the stream.
                    using (StreamReader streamReader = new StreamReader(encStream, oUTF8))
                    {
                        // Read the stream as a string.
                        szResult = streamReader.ReadToEnd();
                        // Close the streams.
                        streamReader.Close();
                    }
                    // Close the CryptoStream.
                    encStream.Close();
                }
                // Close the memory stream.
                memoryStream.Close();
            }
            // Get padding character.
            int nPadding = Convert.ToInt32(szResult[szResult.Length - 1]);
            // Remove padding character for PHP.
            if (nPadding.Equals(4))
            {
                szResult = szResult.Substring(0, szResult.Length - nPadding);
            }
            // Return the decrypted string.
            return szResult;
        }
        /// <summary>
        /// 依據設定的演算法進行資料解密。
        /// </summary>
        /// <param name="encryptedString">被加密的字串。</param>
        /// <param name="key">金鑰字串。</param>
        /// <param name="iv">向量字串。</param>
        /// <returns>原始的字串。</returns>
        public string Decrypt(string encryptedString, string key, string iv)
        {
            string szResult = String.Empty;
            byte[] byBuffer = null;
            // Convert to an array of bytes.
            byBuffer = Convert.FromBase64String(encryptedString);
            // Decrypted bytes to original string.
            szResult = this.DecryptFromBytes(byBuffer, key, iv);
            // Return the decrypted string.
            return szResult;
        }
        /// <summary>
        /// 將 System.Security.Cryptography.AsymmetricAlgorithm 類別目前的執行個體所使用的資源全部釋出。
        /// </summary>
        public void Dispose()
        {
            this.Crypto.Clear();
            this.Crypto.Dispose();
        }
    }
}

Java 範例 (TripleDES):
package sample;

import javax.crypto.*;
import javax.crypto.spec.*;
import javax.xml.bind.DatatypeConverter;

/**
 * TripleDES 加解密服務的類別。
 * @author andychao
 */
public class TripleDES {
    private Cipher oCipher = null;
    private SecretKeySpec specKey = null;
    private IvParameterSpec specIV = null;
    
    public TripleDES(String key, String iv) throws Exception {
        // Create Instance.
        this.oCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        // Decode Key and IV.
        byte[] byKeys = key.getBytes("UTF-8");
        byte[] byIVs = iv.substring(0, 8).getBytes("UTF-8");
        // Duplicate Key the first 8 bytes of the key array.
        if (byKeys.length == 16) {
            byte[] byNewKeys = new byte[24];
            System.arraycopy(byKeys, 0, byNewKeys, 0, 16);
            System.arraycopy(byKeys, 0, byNewKeys, 16, 8);
            byKeys = byNewKeys;
        }
        // Restore Key and IV.
        this.specKey = new SecretKeySpec(byKeys, "DESede");
        this.specIV = new IvParameterSpec(byIVs);
    }
    
    public String Encrypt(String originalValue) throws Exception {
        // Declare variables.
        int nLength = 0;
        String szResult = null;
        // Initialize Cipher of TripleDES.
        this.oCipher.init(Cipher.ENCRYPT_MODE, this.specKey, this.specIV);
        // Convert original value to bytes.
        byte[] bySource = originalValue.getBytes("UTF-8");
        // Get output size for ciphers.
        byte[] byCiphers = new byte[this.oCipher.getOutputSize(bySource.length)];
        // Encrypt data.
        nLength = this.oCipher.update(bySource, 0, bySource.length, byCiphers, 0);
        nLength += this.oCipher.doFinal(byCiphers, nLength);
        // Convert to Base64 string.
        szResult = DatatypeConverter.printBase64Binary(byCiphers);
        // Return encrypted data.
        return szResult;
    }
    
    public String Decrypt(String encryptValue) throws Exception {
        // Declare variables.
        int nLength = 0;
        String szResult = null;
        // Decrypt string as bytes.
        byte[] byCiphers = DatatypeConverter.parseBase64Binary(encryptValue);
        // Initialize Cipher of TripleDES.
        this.oCipher.init(Cipher.DECRYPT_MODE, this.specKey, this.specIV);
        // Get output size for ciphers.
        byte[] bySource = new byte[this.oCipher.getOutputSize(byCiphers.length)];
        // Decrypt data.
        nLength = this.oCipher.update(byCiphers, 0, byCiphers.length, bySource, 0);
        nLength += this.oCipher.doFinal(bySource, nLength);
        // Convert bytes to string.
        szResult = new String(bySource, 0, bySource.length, "UTF-8");
        // Return Decrypted data.
        return szResult;
    }
}

Java 範例 (AES):
package sample;

import javax.crypto.*;
import javax.crypto.spec.*;
import javax.xml.bind.DatatypeConverter;
import java.security.*;

/**
 * AES 加解密服務的類別。
 * @author andychao
 */
public class AES {
    private Cipher oCipher = null;
    private SecretKeySpec specKey = null;
    private IvParameterSpec specIV = null;
    
    public AES(String key, String iv) throws Exception {
        // Create Instance.
        this.oCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        // Decode Key and IV.
        byte[] byKeys = key.getBytes("UTF-8");
        byte[] byIVs = iv.getBytes("UTF-8");
        // Restore Key and IV.
        this.specKey = new SecretKeySpec(byKeys, "AES");
        this.specIV = new IvParameterSpec(byIVs);
    }
    
    public String Encrypt(String originalValue) throws Exception {
        // Declare variables.
        int nLength = 0;
        String szResult = null;
        // Initialize Cipher of AES.
        this.oCipher.init(Cipher.ENCRYPT_MODE, this.specKey, this.specIV);
        // Convert original value to bytes.
        byte[] bySource = originalValue.getBytes("UTF-8");
        // Get output size for ciphers.
        byte[] byCiphers = new byte[this.oCipher.getOutputSize(bySource.length)];
        // Encrypt data.
        nLength = this.oCipher.update(bySource, 0, bySource.length, byCiphers, 0);
        nLength += this.oCipher.doFinal(byCiphers, nLength);
        // Convert to Base64 string.
        szResult = DatatypeConverter.printBase64Binary(byCiphers);
        // Return encrypted data.
        return szResult;
    }
    
    public String Decrypt(String encryptValue) throws Exception {
        // Declare variables.
        int nLength = 0;
        String szResult = null;
        // Decrypt string as bytes.
        byte[] byCiphers = DatatypeConverter.parseBase64Binary(encryptValue);
        // Initialize Cipher of AES.
        this.oCipher.init(Cipher.DECRYPT_MODE, this.specKey, this.specIV);
        // Get output size for ciphers.
        byte[] bySource = new byte[this.oCipher.getOutputSize(byCiphers.length)];
        // Decrypt data.
        nLength = this.oCipher.update(byCiphers, 0, byCiphers.length, bySource, 0);
        nLength += this.oCipher.doFinal(bySource, nLength);
        // Convert bytes to string.
        szResult = new String(bySource, 0, bySource.length, "UTF-8");
        // Return Decrypted data.
        return szResult;
    }
}

PHP 範例 (TripleDES):
/**
 * TripleDES 加解密服務的類別。
 */
class TripleDES {

    private $Key = '1234567890';
    private $IV = '1234567890';
    /**
     * TripleDES 加解密服務類別的建構式。
     */
    function __construct($key, $iv) {
        $this->TripleDES($key, $iv);
    }
    /**
     * TripleDES 加解密服務類別的實體。
     */
    function TripleDES($key, $iv) {
        $this->Key = substr($key . $key, 0, 24);
        $this->IV = substr($iv, 0, 8);
    }
    /**
     * 加密服務的方法。
     */
    function Encrypt($data)
    {
        $szBlockSize = mcrypt_get_block_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_CBC);
        $szPad = $szBlockSize - (strlen($data) % $szBlockSize);
        $szData = mcrypt_encrypt(MCRYPT_TRIPLEDES, $this->Key, $data. str_repeat(chr($szPad), $szPad), MCRYPT_MODE_CBC, $this->IV);
        $szData = base64_encode($szData);

        return $szData;
    }
    /**
     * 解密服務的方法。
     */
    function Decrypt($data)
    {
        $szValue = base64_decode($data);
        $szValue = mcrypt_decrypt(MCRYPT_TRIPLEDES, $this->Key, $szValue, MCRYPT_MODE_CBC, $this->IV);
        $nLength = strlen($szValue);
        $nPadding = ord($szValue[$nLength - 1]);
        $szValue = substr($szValue, 0, $nLength - $nPadding);

        return $szValue;
    }
}

PHP 範例 (AES):
/**
 * AES 加解密服務的類別。
 */
class AES {

    private $Key = '1234567890';
    private $IV = '1234567890';
    /**
     * AES 加解密服務類別的建構式。
     */
    function __construct($key, $iv) {
        $this->AES($key, $iv);
    }
    /**
     * AES 加解密服務類別的實體。
     */
    function AES($key, $iv) {
        $this->Key = $key;
        $this->IV = $iv;
    }
    /**
     * 加密服務的方法。
     */
    function Encrypt($data)
    {
        $szBlockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $szPad = $szBlockSize - (strlen($data) % $szBlockSize);
        $szData = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->Key, $data. str_repeat(chr($szPad), $szPad), MCRYPT_MODE_CBC, $this->IV);
        $szData = base64_encode($szData);

        return $szData;
    }
    /**
     * 解密服務的方法。
     */
    function Decrypt($data)
    {
        $szValue = base64_decode($data);
        $szValue = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->Key, $szValue, MCRYPT_MODE_CBC, $this->IV);
        $nLength = strlen($szValue);
        $nPadding = ord($szValue[$nLength - 1]);
        $szValue = substr($szValue, 0, $nLength - $nPadding);

        return $szValue;
    }
}

Delphi 範例 (AES Ref. kuraki5336 網誌):
{ TODO: xStr 明文, xKey 加密金鑰 xIV 加密向量 }
function EncryAES(xStr, xKey, xIV: AnsiString): String;
var
    Source: TStringStream;
    Dest: TStringStream;
    { TODO: 引用 ELAES.PAS 就會認識了 }
    mKey: TAESKey128;
    mIV: TAESBuffer;
    strRemainder, i: Integer;
    mstr, aKey, aIV: Ansistring;
begin
    try
        { TODO: 不要覺得奇怪,不這樣重給,值就是會不對  } 
        { TODO: ※我外部傳入其實已經是ANSISTING了不知道為什麼直接使用上面的xStr xKey 這載入的值就會有異常。因此從新給一次※ } 
        mstr := xStr;
        aKey := xKey;
        aIV :=xIV;
        { TODO: pksc5  PHP 是用pksc5 但是DELPHI & JAVA 就是要用pksc5才會對  }
        { TODO: ※補位的主要原因是在   EncryptAESStreamCBC 會檢核你輸入的數值是否有達到128K 192K 248K 因此來源值需要補位※ } 
        strRemainder :=Length(mstr) mod 16;
        strRemainder := 16 - strRemainder;
        for i := 1 to strRemainder do
        begin
            mstr := mstr + Chr(strRemainder);
        end;
        { TODO: KEY & IV 將KEY轉成Array of Byte }
        FillChar( mKey, SizeOf(mKey), #0 );
        Move( PAnsiChar(aKey)^, mKey, 16);
        FillChar( mIV, SizeOf(mIV), #0 );
        Move( PAnsiChar(aIV)^, mIV, 16);
        { TODO: Input & output 並賦予值 }
        Source := TStringStream.Create(mstr, 65001);
        Dest   := TStringStream.Create('', 65001);
        { TODO: 加密 }
        EncryptAESStreamCBC( Source, 0, mKey, mIV, Dest );
        { TODO: BASE64 千萬不要對Dest做任何的變化,保持BYTE來做加解密}
        Result := EncodeBase64(Dest.Bytes, Dest.size);
    finally
        Source.Free;
        Dest.Free;
    end;
end;

{ TODO: 再回傳上有一組資訊是被加密過得因此我們必須解密才能得到裡面的值做紀錄 }
{ TODO: xStr的值會是ALLPAY回應給我們的加密電文 , 因此要按照當初加密的方式反向解密 }
function DecryptAES(xStr, xKey, xIV: AnsiString): String;
var
    Source: TStringStream;
    Dest: TStringStream;
    mKey: TAESKey128;
    mIV: TAESBuffer;
    strRemainder,i:Integer;
    mstr,aKey,aIV:Ansistring;
    mBytes, mReturnByte :TBytes;
begin
    try
        { TODO: Input & output }
        Dest := TStringStream.Create('', 65001);
        Source := TStringStream.Create('', 65001);
        { TODO: 不要覺得奇怪,不這樣重給,值就是會不對 } 
        mstr := xStr;
        aKey := xKey;
        aIV := xIV;
        { TODO: 反解密.DecodeBase64 }
        mBytes := DecodeBase64(mstr);
        { TODO: 將資料已Byte方式輸入...千千萬萬不要.....拿字串輸入哦 }
        { TODO: 不可以這樣寫 Source.WriteBuffer(mBytes, mBytes.size); 寫進去的值根本不對。我不知道為什麼@@ }
        Source.Position := 0;
        for i := 0 to length(mBytes) -1 do
        begin
            Source.WriteBuffer(mBytes[i], 1);
        end;
        { TODO: 不用補位 }
        { TODO: KEY & IV 將KEY轉成Array of Byte }
        FillChar( mKey, SizeOf(mKey), #0 );
        Move( PAnsiChar(aKey)^, mKey, 16);
        FillChar( mIV, SizeOf(mIV), #0 );
        Move( PAnsiChar(aIV)^, mIV, 16);
        { TODO: 解密 }
        DecryptAESStreamCBC( Source, 0, mKey, mIV, Dest );
        { TODO: 濾掉byte < 32 --小於32的都是特殊字元對於解析無意義}
        Dest.Position := 0;
        SetLength(mReturnByte, Dest.size);
        for i := 0 to Dest.size do
        begin
           if (Dest.Bytes[i] <= 32) then
              continue;
           Dest.Read(mReturnByte[i], 1);
        end;
        { TODO: 轉字串 }
        Result := Dest.DataString;
    finally
        Source.Free;
        Dest.Free;
    end;
end;

以上的範例,

眼尖的朋友會發現,

為什麼其他語言都是 PKCS5,

而 .NET 是使用 PKCS7,

但是加解密是可以互通的呢?!

原因是 PKCS5 與 PKCS7 裡使用的填補演算法是相同~~


就醬~打完收工~~


在 Blogger 使用 Google Code Prettify 程式碼美化區塊筆記

Google Code Prettify 是一個簡單易用的程式碼高亮度顯示程式。
  • 支援支援多種程式語言
  • 僅需載入一個檔案
  • 可以自訂修改樣式

以下簡單示範如何在 Blogger 設定使用 Google Code Prettify。


Step 1: 加入 Google Code Prettify 語法支援設定

請先到網誌的版面配置頁面,如下圖:


拉到該畫面最下方,選擇任意一個新增小工具。


選擇加入 HTML/JavaScript 小工具。


在小工具中打上標題,在內容中貼上程式碼,並按下儲存按鈕,這樣就完成了設定。如下程式碼與圖例:
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>



Step 2: 在文章中貼上程式碼

在撰寫新文章時選擇 HTML方式撰寫程式碼。


接著在撰寫網誌原始碼的地方以 <pre> 標籤範圍內撰寫或貼上程式碼。如下:
<pre class="prettyprint">
<code class="language-html">
你的程式碼...
</code>
</pre>

要特別注意的是,如果程式碼有 "&"、"<"、">" 這三個符號,需將 "&" 轉換為 "&amp;"、"<" 轉換為 "&lt;"、">" 轉換為 "&gt;";若覺得麻煩,也可使用些線上轉換的小工具 Online HTML Encode/Decode 轉換完後再貼上。


Step 3: 變更程式碼顯示樣式

Google Code Prettify 提供幾個程式碼的顯示樣式(Skin Gallery),只要回到 HTML/JavaScript 小工具,編輯原本貼上的程式碼,加上 skin 參數,並指定想顯示的 skin 名稱即可。使用方式如下:
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>

如果想在程式碼區塊顯示行號,需要在 <pre> 標籤的 class 屬性中加入 linenums 的樣式,如下:
<pre class="prettyprint linenums">
<code class="language-html">
你的程式碼...
</code>
</pre>

若想要在程式碼區塊的每一行都顯示行號,可以在 HTML/JavaScript 小工具加入以下 CSS 程式碼:
<style type="text/css">
li.L0, li.L1, li.L2, li.L3, li.L5, li.L6, li.L7, li.L8 { list-style-type: decimal !important }
</style>

如果 Google Code Prettify 的樣式你不喜歡,而你也很熟悉 CSS,也可以參考 Google Code Prettify 提供的樣式進行些微調。

就醬囉~