Monthly Archives: 五月 2021

[T-SQL] 從資料記錄裡面抽出 IP


在自訂的事件紀錄裡面,由程式碼觸發的自動紀錄,原先只是當作備查用,就如同 Windows 內建的事件檢視器,資料庫欄位有 事件類別、事件代碼、事件時間、事件內容等,並沒有把 IP 當作獨立欄位拉出來,IP 會出現在事件內容的任何地方。

最近覺得系統效能不太正常,想確認是否有異常攻擊,打算依照 IP 來做排序計算,就變成一個困擾。

好在,不用管 IPv6 或是 domain name ,原先全部都有轉換成 IP 。

檢視資料紀錄後,發現 IP 大概有幾種紀錄格式存在事件內容中,有可能出現在一開始、中間或最末行:

IP=xx.xx.xx.xx
IP:xx.xx.xx.xx
IP: xx.xx.xx.xx
yy=xx.xx.xx.xx
yy:xx.xx.xx.xx

T-SQL 語法中並沒有正規運算式可用,所以組出來很麻煩,我組出來大概是這樣:

'%[:=]%[0-9]%.[0-9]%.[0-9]%.[0-9]%'
項目說明
%[:=]%先找出 yy: 或 yy= ,並包含可能有空白的項目
[0-9]%. IP 由數字開頭,1~3位數,後接小數點
[0-9]% 第四碼 IP 後方不知道還有多長
條件項目說明

測試的 T-SQL 語法為:

SELECT *, LEFT(cl, PATINDEX('%[^.0-9]%', cl) - 1) AS cIP	
FROM (
	SELECT *, (TRIM(SUBSTRING(cs, PATINDEX('%[:=]%[0-9]%.[0-9]%.[0-9]%.[0-9]%', cs) + 1, 17)) + ' ') AS cl
	FROM (
		SELECT ' IP: 172.16.1.1 User' AS cs
	) AS ts
) AS ts

因為條件式只能抓到滿足的 事件內容 ,我的重點是要抽出 IP ,所以用 SubString 抓出中間字串,利用 PatIndex 抓到符合的開始位置,因為不確定 IP 的具體長度,先抓 17 個長度下來。

接下來要把 IP 尾端無效內容去除,由於 IP 由數字 0 ~ 9 跟小數點組成,所以比較單純,直接把其他字元抓出來砍。由於 IP 可能會出現在最後,所以在前一段先加一個空白字元,確保這段可以找到非 IP 的字元進行運算。

會這麼繞,是真的不知道 T-SQL 可以怎樣抽 IP 出來,只能先抓開頭,再減尾巴,最後把 IP 剪出來,如果有更好的方法,也請不吝分享。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Web] JavaScript 迴圈隱式變數是全域變數


很少有機會在網頁裡面寫遞迴。最近剛好有個邏輯要用遞迴,結果寫下去就變無窮迴圈了…

所以我做了個簡單的測試範例後,用這個範例萬事問臉書。如下圖:

EnumData 為一個列舉資料的遞迴函數測試範例

當時我並沒有注意到右邊箭號的分區。

這張圖中,變數 ibd 是一個在迴圈內的隱式宣告,一般迴圈的範例都是這樣,所以我也照用了,而在遞迴呼叫中,被呼叫的 ibd 會被重置為 0 ,以至於上層的迴圈永遠無法跑到 2 ,永遠就在 0, 1 打轉。

黃忠成老師給個建議,改用:

for (let ibd=0; ibd<dbArray.length; ibd++){

果然可以。但是我的網頁需要相容 IE 舊版,經查 let 為 ES6 (ES2015) 的規範,所以在 IE 舊版並不支援。

就在苦無對策的時候,忽然發現,右側視窗中,ibd 在全域變數內?隱式宣告預設是全域變數不是區域變數?我一直以為隱式宣告是類似 using 之類的區塊變數,只在迴圈中有效。

既然知道是全域變數,就改成:

var ibd;
for (ibd=0; ibd<dbArray.length; ibd++){

則 ibd 變成函數層級的變數,其實變成函數層級變數就可以了,到不用勉強一定要區域變數,這樣遞迴的變數就不會互相干擾,搞定收工。

當然我也測過 Chrome ,不過截圖就用以 Chrome 為底的 Edge ,因為開發工具畫面是中文,比較親善:

迴圈變數的隱式宣告在 Chrome 也是全域變數

開發者要養成寫測試專案或測試例,這樣有助於縮小範圍鎖定問題,也容易跟其他人溝通。

謝謝黃忠成老師。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

在 WordPress.com 建立免費網站或網誌.

%d 位部落客按了讚: