2021年3月8日月曜日

iMovie9.09のインストール

 旧いiMovieを使いたいなーと思ってたらアップデートファイルから取れるらしいとのこと。

旧バージョンのiMovieを入れる方法

iMovie ver 10って、テキストのフェードインフェードアウトが調整できないんですよね。 ver 9にしたいなあ。 と思ったら、なかなかダウングレードする方法が見つからない。 最終的に、以下の方法でうまくいきました。 (環境:mac OS X El Capitan 10....

Install iMovie 9 or iTunes 12.6.2 on El Capitan – OS X 10.11

We had a student needing to get iMovie on her Mid 2012 MacBook Pro running El Capitain 10.11.6. Apple makes it hard to get older apps running on old OSes, but we have a workaround. NOTE: this metho…

ざっくり書くとこんな感じ

  1. アップルのサイトからアップデートファイルをダウンロードする
  2. pkgutil コマンドを使って解凍
  3. pkgファイルを開いてpayloadをpayload.zipへリネーム。
  4. payload.zipを解凍
  5. その中のApplicationフォルダにiMovie.appがあるので、適当に配置

試したら上手くいった。バンザイ。

2021年2月9日火曜日

またまたMac mini買いました

 懲りもせずまたまたマックをメルカリで買いました。

もう終わりにしなくては・・・。

Mac mini 2010

2021年1月1日金曜日

いらっしゃ2021年、バイバイ2020年

激動の年が終わりましたね。今生きている人にとっては人生最大の出来事だったのかなーって思ってしまいます。

2021年はワクチンもできて一般に接種できるのでしょうか。

少なくとも去年よりはマシになってくれるといいのですが…。

2020年7月15日水曜日

2013年11月28日木曜日

vbaでbase64エンコード

勉強を兼ねて作ってみました。

いろいろなページをみましたが、下記が分かりやすかったです。
http://www.kumei.ne.jp/c_lang/sdk3/sdk_235.htm
http://www.kumei.ne.jp/c_lang/sdk3/sdk_237.htm

Public Function Base64Encode(b() As Byte) As String
  Dim bytBase64() As Byte '変換テーブル
  Dim bytSTR() As Byte    'エンコード後の文字列を格納する変数
  Dim lngSize As Long     '元のサイズを入れておく変数
  Dim i As Integer, j As Integer

  If Not IsArray(b) Then Exit Function

  '変換テーブル
  bytBase64 = StrConv("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", vbFromUnicode)

  '引数のサイズを調べておく
  lngSize = UBound(b)

  'とりあえず4倍は確保して多く
  ReDim bytSTR((UBound(b) + 1) * 4 + 1)

  '3バイトの倍数になるように足りないバイト数を ReDim Preserve する(ゼロ埋めしなくていいのかな?)
  If (lngSize + 1 + 3) Mod 3 = 1 Then
    ReDim Preserve b(lngSize + 2) '2バイト増やす
  End If
  If (lngSize + 1 + 3) Mod 3 = 2 Then
    ReDim Preserve b(lngSize + 1) '1バイト増やす
  End If

  '3バイトずつエンコード
  j = 0
  For i = 0 To UBound(b) Step 3
    '10進数 = 16進数 = 2進数 : 3 = &H03 = 00000011, 15 = &H0F = 00001111, 63 = &H3F = 00111111
    bytSTR(j) = bytBase64(Int(b(i) / (2 ^ 2)))                                              '右に2ビットシフト
    bytSTR(j + 1) = bytBase64(Int((b(i) And &H3) * (2 ^ 4)) + Int(b(i + 1) / (2 ^ 4)))      '上位6ビットを0にしてこれを4ビット左シフトして、次の要素を右に4ビットシフトして足す
    bytSTR(j + 2) = bytBase64(Int((b(i + 1) And &HF) * (2 ^ 2)) + Int(b(i + 2) / (2 ^ 6)))  '上位4ビットを0にしてこれを2ビット左シフトして、次の要素を右に6ビットシフトして足す
    bytSTR(j + 3) = bytBase64(Int(b(i + 2) And &H3F))                                       '上位2ビットを0にする
    j = j + 4 'エンコードは4バイトずつ進む
  Next

  'pad処理(足りない部分は'='で埋める)
  If (lngSize + 1) Mod 3 = 1 Then
    bytSTR(j - 2) = AscB("=")
    bytSTR(j - 1) = AscB("=")
  End If
  If (lngSize + 1) Mod 3 = 2 Then
    bytSTR(j - 1) = AscB("=")
  End If

  'いらない部分は削除
  ReDim Preserve bytSTR(j - 1)

  Base64Encode = StrConv(bytSTR, vbUnicode)
End Function


2013年11月18日月曜日

HTAでTwitter Bootstrapを試す

よくネットで調べるとtwitter bootstrapをHTAで使うと悲惨的な書き込みを見かけますが、下記試すと少しだけ幸せになれそうです。

<meta http-equiv="X-UA-Compatible" content="IE=9"/>

before

after

enjoy

2012年11月19日月曜日

VBAで設定ファイルの読み込み

なんとなく設定ファイルを読み込む関数を作ろうかと思って書いてみた。
Dictionaryで返します。


Option Explicit

'設定ファイルを読み込んでDictionaryで返す
Public Function GetConfig(strFileName)
  Dim RegExp    'VBScript_RegExp_55.RegExp
  Dim Match     'VBScript_RegExp_55.Match
  Dim Matches   'VBScript_RegExp_55.MatchCollection
  Dim dict      'Scripting.Dictionary
  Dim fso       'Scripting.FileSystemObject
  Dim strData   'ファイルのデータ
  Dim i
  
  'RegExp Setting
  Set RegExp = CreateObject("VBScript.RegExp")
  RegExp.IgnoreCase = False '大文字小文字を区別する
  RegExp.Global = True
  RegExp.MultiLine = True   '複数行を対称にする
  RegExp.Pattern = "^(\S+)\s*=\s*(\S+)*\s*$"
  
  'Dictionary(keyは大文字小文字を区別する)
  Set dict = CreateObject("Scripting.Dictionary")
  
  'FilesyStemObject
  Set fso = CreateObject("Scripting.FileSystemObject")
  
  'ファイルチェック
  If Not fso.FileExists(strFileName) Then
    Set GetConfig = dict
    Set dict = Nothing
    Set fso = Nothing
    Exit Function
  End If
  
  'ファイル読み込み
  With fso.OpenTextFile(strFileName)
    strData = .ReadAll
  End With
  Set fso = Nothing
  
  '取り出し
  Set Matches = RegExp.Execute(strData)
  For Each Match In Matches
    dict(Match.SubMatches(0)) = Match.SubMatches(1)
  Next
  
  Set GetConfig = dict
  
  Set RegExp = Nothing
  Set Matches = Nothing
  Set Match = Nothing
  Set dict = Nothing
End Function

一応、vbscriptも意識してみたつもり。

2012年9月30日日曜日

ExcelでJsonデータを取得する

どうにかエクセルでjsonデータを取得できないか考えて、いろいろ探しましたが、ScriptControlを使うものしか見つからなかったので、コロンブスの卵的な発想でVBAでIEのHTMLDocumentオブジェクトを作ってその内部でJavaScriptに処理してもらった後、結果をもらうことにしてみました。 以下コード。
Option Explicit

'Microsoft WinHTTP Services, version 5.1 に参照設定

'WinHttpRequest proxy settings.
Const HTTPREQUEST_PROXYSETTING_DEFAULT = 0
Const HTTPREQUEST_PROXYSETTING_PRECONFIG = 0
Const HTTPREQUEST_PROXYSETTING_DIRECT = 1
Const HTTPREQUEST_PROXYSETTING_PROXY = 2
'Specifies when IWinHttpRequest uses credentials. Can be one of the following values.
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = &H0
Const HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = &H1


Sub tweet_search_json()
  Dim req As New WinHttp.WinHttpRequest
  Dim js As String
  Dim doc As Object
  Dim obj As Object
  
  req.Option(WinHttpRequestOption_UserAgentString) = "Mozilla/4.0 "
  req.Open "GET", "http://search.twitter.com/search.json?q=okinawa", False
  req.Send
  
  'JavaScript
  js = "json = (<<json_response>>);" & _
       "for( var i in json.results){ " & _
           "var elm = document.createElement('div');" & _
           "elm.innerHTML = json.results[i].text;" & _
           "document.getElementsByTagName('body').item(0).appendChild(elm);" & _
       "}"
  
  'IEの HTMLDocument オブジェクトを作る
  Set doc = CreateObject("htmlfile")
  
  ' スクリプト実行
  doc.parentWindow.execScript Replace(js, "<<json_response>>", req.ResponseText), "JavaScript"
  For Each obj In doc.getElementsByTagName("div")
    Debug.Print obj.FirstChild.nodevalue
  Next
  
  Set req = Nothing
  Set doc = Nothing
  Set obj = Nothing
End Sub


「Microsoft WinHTTP」が必要です。(おそらくWin2000以降はインストールされているはず)

2012年1月11日水曜日

win機へubuntuをインストール

年末になんとなくubuntuを使いたくなったので、手元のノートパソコンへインスールすることにしました。
パソコンの仕様は
TOSHIBA dynabook BX(PABX33ML)
CPU インテル® Pentium® プロセッサー P6000(1.86GH)
チップセット インテル® HM55 Expres
HDD 320GB
メモリ 2GB
という、linuxには快適すぎる環境。適当に空きパーテーションをつくる。
Ubuntu9.04のCDがあったので、そのままインストール。
10.04LTSを入れたかったので、AlternateCD版をダウンロード・CD-Rへ焼いて再起動すると、「アップグレード対象外」との事。
9.10からなら一発で行けるそうなので、9.10のAlternateCD版をダウンロードして
$ mkdir /mnt/Alternate $ sudo mount -o loop ~/Desktop/ubuntu-09.10-alternate-i386.iso /mnt/Alternate
でマウント。
$ gksu "sh /mnt/Alternate/cdromupgrade"
するとなぜかリポジトリエラー。
なので、無理やり vi /etc/apt/sources.list して以下の行を追加。
deb file:/mnt/Alternate main
deb-src file:/mnt/Alternate main #必要か不明
保存したら、
$ sudo apt-get update
$ sudo apt-get dist-upgrade
でアップグレード実行。
今度はうまくいったので、さっき作った10.04LTSのAlternate版を使ってアップグレード
(今度はCD入れたら自動でやってくれました。)

でめたく10.04へアップグレードして再起動すると。Xが真っ黒。
手探りでユーザ名とパスワード入れるとXは立ち上がっている模様。
チップセットが対応していないようなので、リカバリーモードで起動してX.orgを書き換え。
この辺を参考に
Section "Device"
Identifier "Configured Video Device"
Driver "vesa"
EndSection
とかしながら、何とか低グラフィックモードで起動できたので、
$sudo apt-get update
$sudo apt-get upgrade
すると認識して通常通り起動しました。
bootまわりはここを参照。

あとはAcpiまわりを対策すれば完璧。

2012年1月10日火曜日

2011年10月9日日曜日

iPhone4S販売決定

ついにsoftbankとauからiPhone4Sが発表になりました。
最初はsoftbankを解約してauの携帯をiPhone4Sにしようかと思いましたが、softbankの発表を聞いて現状のままauは携帯、softbankはiPhoneで行くことに決定。
3GSユーザなので、さっそく予約。 家族会議の結果、追加料金が出なければ機種変OKとのことなので16gbを予約しました。

初日はシステムダウンするほどの申し込みだったようです。
14日に受け取りできるんだろうか・・・。

楽しみですね。

softbankのiPhoneページ
http://mb.softbank.jp/mb/iphone/

auのiPhoneページ
http://www.au.kddi.com/iphone/

2011年7月13日水曜日

sqlite3のDLLを作る。

諦めていたわけではないのですが・・・。
mingw32を使うと割とスムーズにできたので・・・。

まずは、sqlite3ダウンロードページからソースが一つにまとめられた amalgamation 版をダウンロードします。
で、コマンドプロンプトでダウンロードしたフォルダへ移動して


>c:\MinGW\bin\gcc -mrtd -c -O2 -DSQLITE_THREADSAFE=1 -DSQLITE_API="__declspec(dllexport)" sqlite3.c

でコンパイルして

>c:\MinGW\bin\gcc -shared -o sqlite3.dll sqlite3.o -Wl,--add-stdcall-alias,--kill-at,--out-def=sqlite3.def

でDLLが出来上がります。

この方法だと__stdcallで出来上がるそうなので、vbから呼び出しokです。
(-mrtdを渡すことで既定の規約を__stdcallへ変更できる)

sqlite使って遊びましょう。

2011年6月18日土曜日

2011年6月9日木曜日

vbaでHTMLダイアログ

便利だけどあまりwebに見つからないので。
インターネットでもローカルファイルでも行けます。
Option Explicit

'HRESULT CreateURLMoniker(
'    IMoniker *pMkCtx,
'    LPCWSTR szURL, //ワイド文字
'    IMoniker **ppmk
');
'
'HRESULT ShowHTMLDialog(
'    HWND hwndParent,
'    IMoniker *pMk,
'    VARIANT *pvarArgIn,
'    LPWSTR pchOptions, //ワイド文字
'    VARIANT *pvarArgOut
');


Private Declare Function CreateURLMoniker Lib "urlmon.dll" _
  (ByVal pMkCtx As Long, _
  ByVal szURL As Long, _
  ByRef ppmk As Long) As Long
Private Declare Function ShowHTMLDialog Lib "mshtml.dll" _
  (ByVal hwndParent As Long, _
  ByVal pMk As Long, _
  ByVal pvarArgIn As Long, _
  ByVal pchOptions As Long, _
  ByVal pvarArgOut As Long) As Long
Private Const S_OK = 0
Private Const E_OUTOFMEMORY = &H8007000E
Private Const MK_E_SYNTAX = &H800401E4

'pchOptions
'dialogHeight:sHeight
'dialogLeft:sXPos
'dialogTop:sYPos
'dialogWidth:sWidth
'center:{ yes | no | 1 | 0 | on | off }
'dialogHide:{ yes | no | 1 | 0 | on | off }
'edge:{ sunken | raised }
'resizable:{ yes | no | 1 | 0 | on | off }
'scroll:{ yes | no | 1 | 0 | on | off }
'status:{ yes | no | 1 | 0 | on | off }
'unadorned:{ yes | no | 1 | 0 | on | off }

Sub test()
  Dim moniker As Long
  Dim szURL As String
  Dim ret As Long
  
  Const options = "help:no; status:no; dialogWidth:460px; dialogHeight=320px"
  szURL = "http://www.google.co.jp"
  'szURL = "file://c:/test.htm"
  ret = CreateURLMoniker(0, StrPtr(szURL), moniker)
   
  If ret = S_OK Then
    
    ret = ShowHTMLDialog(0, moniker, 0, StrPtr(options), 0)
    
    If ret = S_OK Then
      MsgBox "成功"
    Else
      MsgBox "失敗"
    End If
  
  End If
   
End Sub

便利!

2011年4月30日土曜日

VBAでのURLエンコード

前の記事でコメントをいただきましたので、自分ならこうするだろうということで。

Function UrlEncode(strTarget As String) As String
  Dim obj As Object
  Dim s As String

  If Len(strTarget) = 0 Then Exit Function
  
  Set obj = CreateObject("ScriptControl")
  obj.Language = "JScript"
  s = obj.CodeObject.encodeURIComponent(strTarget)
  'エンコードされないので文字の対策
  s = Replace(s, "(", "%28") '(
  s = Replace(s, ")", "%29") ')
  s = Replace(s, "!", "%21") '!
  UrlEncode = s
End Function

手抜きまくってます・・・。

2011年2月16日水曜日

VB/VBAでTwitter

なんとかVBAで出来ないかといろいろ調べて、何とかできました。

このページを参考にしました。

Twitter API を OAuth で認証するスクリプトを 0 から書いてみた - trial and error

どうも。昨日もちょっと twitter に触れましたが、今日も twitter ねたです。

前の post で、チラッと触れた OAuth 認証 (O認証認証みたいでこわい) を使ってみたくなり、自分で 0 から書いて見ました。

windows2000、IE6、ms-office2000以降なら動くと思います。

Private Declare Function CryptBinaryToString Lib "crypt32.dll" Alias "CryptBinaryToStringA" _
    (ByRef pbBinary As Any, _
     ByVal cbBinary As Long, _
     ByVal dwFlags As Long, _
     ByVal pszString As String, _
     ByRef pcchString As Long _
     ) As Long
Private Const CRYPT_STRING_BASE64  As Long = 1

Private Const consumer_key = "consumer-key"
Private Const consumer_secret = "consumer-securet"

Private Const reqt_url = "http://twitter.com/oauth/request_token"
Private Const auth_url = "http://twitter.com/oauth/authorize"
Private Const acct_url = "http://twitter.com/oauth/access_token"
Private Const post_url = "https://twitter.com/statuses/update.xml"
Private Const frtl_url = "http://twitter.com/statuses/friends_timeline.xml"

'Proxyを使う場合はユーザ名:パスワードで指定
'Private Const proxy_user = ""

Sub test()
  Dim XHR As New MSXML2.XMLHTTP 'IEのxmlHttpRequestと同じ(クッキー・プロキシも同じ設定を使う)
  Dim param As Scripting.Dictionary
  Dim reqdata As String
  Dim digest As String
  Dim buf() As Byte
  Dim res As String
  Dim XMLDOM As MSXML2.DOMDocument
  Dim proxy_auth As String
  Dim otoken As String, otoken_secret As String
  Dim atoken As String, atoken_secret As String
  Dim pin As String


  If Len(proxy_user) > 0 Then
    proxy_auth = EncodeBase64(StrConv(proxy_user, vbFromUnicode))
  End If
  
  Set param = CreateObject("Scripting.Dictionary")
  '共通
  param("oauth_consumer_key") = consumer_key
  param("oauth_signature_method") = "HMAC-SHA1"
  param("oauth_version") = "1.0"
  
  '毎回必要
  param("oauth_timestamp") = CStr(DateDiff("s", #1/1/1970#, Now()))
  param("oauth_nonce") = param("oauth_timestamp") * 333333 '適当にかぶらない数字
  reqdata = "GET&" & UrlEncode(reqt_url) & "&" & UrlEncode(UrlParse(param))
  digest = hmac(consumer_secret & "&", reqdata)
  buf = StrToBynary(digest)
  param("oauth_signature") = Trim(EncodeBase64(buf))
  
  Call XHR.Open("GET", reqt_url & "?" & UrlParse(param), False)
  If Len(proxy_user) > 0 Then
    Call XHR.SetRequestHeader("Proxy-Authorization", "Basic " & proxy_auth)
  End If
  XHR.Send
  Debug.Print "リクエストトークンをリクエスト レスポンスコード:"; XHR.status
  
  'authトークン(一時的に使う為)
  otoken = GetOAuthToken(XHR.ResponseText)
  otoken_secret = GetOAuthToken_secret(XHR.ResponseText)
  
  'PIN取得の為IEを起動(引数にauthトークンを指定)
  Shell "c:\Program Files\Internet Explorer\iexplore.exe " & auth_url & "?oauth_token=" & otoken
  pin = InputBox("pinを入力")
  If pin = "" Then Exit Sub
  
  '作り直し
  param.Remove ("oauth_signature")
  param("oauth_timestamp") = CStr(DateDiff("s", #1/1/1970#, Now()))
  param("oauth_nonce") = param("oauth_timestamp") * 333333
  param("oauth_verifier") = pin '今回だけ(PINコード)
  param("oauth_token") = otoken '今回だけ(authトークン)
  reqdata = "GET&" & UrlEncode(acct_url) & "&" & UrlEncode(UrlParse(param))
  digest = hmac(consumer_secret & "&" & otoken_secret, reqdata)
  buf = StrToBynary(digest)
  param("oauth_signature") = Trim(EncodeBase64(buf))
  
  Call XHR.Open("GET", acct_url & "?" & UrlParse(param), False)
  If Len(proxy_user) > 0 Then
    Call XHR.SetRequestHeader("Proxy-Authorization", "Basic " & proxy_auth)
  End If
  XHR.Send
  Debug.Print "アクセルトークンをリクエスト レスポンスコード:"; XHR.status

  'アクセストークン(今のところ期限が無いので恒久的。次回はいきなり指定してもOK)
  atoken = GetOAuthToken(XHR.ResponseText)
  atoken_secret = GetOAuthToken_secret(XHR.ResponseText)

  '作り直し
  param.Remove ("oauth_verifier")
  param.Remove ("oauth_signature")
  param("oauth_timestamp") = CStr(DateDiff("s", #1/1/1970#, Now()))
  param("oauth_nonce") = param("oauth_timestamp") * 333333
  param("oauth_token") = atoken
  param("count") = "50"
  reqdata = "GET&" & UrlEncode(frtl_url) & "&" & UrlEncode(UrlParse(param))
  digest = hmac(consumer_secret & "&" & atoken_secret, reqdata)
  buf = StrToBynary(digest)
  param("oauth_signature") = Trim(EncodeBase64(buf))
  
  Call XHR.Open("GET", frtl_url & "?" & UrlParse(param), False)
  If Len(proxy_user) > 0 Then
    Call XHR.SetRequestHeader("Proxy-Authorization", "Basic " & proxy_auth)
  End If
  XHR.Send
  Debug.Print "APIアクセス レスポンスコード:"; XHR.status
  
  Dim status As MSXML2.IXMLDOMSelection
  Dim texts As MSXML2.IXMLDOMElement
  Dim i As Long
  Set XMLDOM = XHR.responseXML
  Set status = XMLDOM.getElementsByTagName("status")
  For Each texts In status
      Debug.Print ConvertCreateTime(texts.selectSingleNode("created_at").FirstChild.NodeValue);
      Debug.Print texts.selectSingleNode("user/screen_name").FirstChild.NodeValue; ": ";
      Debug.Print texts.selectSingleNode("text").FirstChild.NodeValue
  Next
    
End Sub

'wsh機能を使う(JScript)
Private Function UrlEncode(strTarget As String) As String
  Dim obj As Object
  If Len(strTarget) = 0 Then Exit Function
  Set obj = CreateObject("ScriptControl")
  obj.Language = "JScript"
  UrlEncode = obj.CodeObject.encodeURIComponent(strTarget)
End Function

'win32API(恐らくwin2000から動く)
Function EncodeBase64(bytTarget() As Byte) As String
  Dim strBase64 As String
  Dim lngBase64_Len As Long
  Dim ret As Long
  '必要な容量を計算
  ret = CryptBinaryToString(bytTarget(0), UBound(bytTarget) + 1, CRYPT_STRING_BASE64, vbNullString, lngBase64_Len)
  If ret Then
      strBase64 = Space(lngBase64_Len)
      ret = CryptBinaryToString(bytTarget(0), UBound(bytTarget) + 1, CRYPT_STRING_BASE64, strBase64, Len(strBase64))
  End If
  EncodeBase64 = Mid(strBase64, 1, lngBase64_Len - 3)
End Function

'keyをソートして配列を返す
Private Function KeySort(dic As Scripting.Dictionary) As Variant
  Dim i As Long, j As Long
  Dim varTemp As Variant
  Dim varData As Variant
  
  If dic Is Nothing And dic.Count = 0 Then
    Exit Function
  End If
  
  varData = dic.Keys
  
  '総当りでソート(バブルソート)
  For i = 0 To dic.Count - 1
    For j = i + 1 To dic.Count - 1
      '比較
      If varData(i) > varData(j) Then
        varTemp = varData(i)
        varData(i) = varData(j)
        varData(j) = varTemp
      End If
    Next
  Next
  
  KeySort = varData
End Function

'dictionaryオブジェクトのキーをソートしてkey1=value1&key2=valu2...の文字列を返す
Private Function UrlParse(dictionary_object As Scripting.Dictionary) As String
  Dim strReqData As String
  Dim d As Variant
  Dim i As Long
  On Error Resume Next
  d = KeySort(dictionary_object)
  For i = 0 To UBound(d)
    strReqData = strReqData & "&" & CStr(d(i)) & "=" & dictionary_object(d(i))
  Next
  If Err.Number = 0 Then
    UrlParse = Mid(strReqData, 2)
  Else
    UrlParse = ""
  End If
  On Error GoTo 0
End Function

'暗号化
Private Function hmac(ByVal key As String, ByVal data As String) As String
  Dim i As Integer
  Dim hash As String
  Dim key_byte() As Byte
  Dim key_len As Long
  Dim data_len As Long
  Dim ipad(63) As Byte
  Dim opad(63) As Byte
  Dim key_hash() As Byte
  Dim data_hash As String

  If key = "" And data = "" Then Exit Function

  key_len = Len(key)

  key_byte = StrConv(key, vbFromUnicode)
  If key_len > 64 Then
      key_hash = StrToBynary(CreateSHA1Hash(key_byte))
      key_len = 20
  Else
      key_hash = key_byte
  End If
  
  ReDim Preserve key_hash(63)
  For i = key_len To 63
    key_hash(i) = 0
  Next

  For i = 0 To 63
    ipad(i) = 0
    opad(i) = 0
  Next

  For i = 0 To 63
    ipad(i) = key_hash(i) Xor &H36
    opad(i) = key_hash(i) Xor &H5C
  Next

  data_hash = CreateSHA1Hash(CStr(ipad) & StrConv(data, vbFromUnicode))

  hash = CreateSHA1Hash(CStr(opad) & CStr(StrToBynary(data_hash)))

  hmac = hash
End Function

'バイト文字列からバイト配列を返す
Private Function StrToBynary(strHexString As String) As Byte()
  Dim buf() As Byte
  Dim i As Long
  
  ReDim Preserve buf(Len(CStr(strHexString)) \ 2 - 1)
  For i = 0 To Len(CStr(strHexString)) \ 2 - 1
    buf(i) = CByte("&h" & Mid(CStr(strHexString), i * 2 + 1, 2))
  Next
  StrToBynary = buf
End Function

'TwitterAPIの作成日から日付型の変数を返す
Private Function ConvertCreateTime(strCreated_at As String) As Date
  ConvertCreateTime = DateValue(Mid(strCreated_at, 5, 6) & Right(strCreated_at, 5)) + TimeValue(Mid(strCreated_at, 11, 9)) + TimeValue("09:00")
End Function

'TwitterAPIのレスポンスからTokenを抜き出す
Private Function GetOAuthToken(strTarget As String) As String
  Dim s, a, v
  s = Split(strTarget, "&")
  For Each a In s
    v = Split(a, "=")
    If v(0) = "oauth_token" Then
      GetOAuthToken = v(1)
      Exit Function
    End If
  Next
End Function

'TwitterAPIのレスポンスからsecretを抜き出す
Private Function GetOAuthToken_secret(strTarget As String) As String
  Dim s, a, v
  s = Split(strTarget, "&")
  For Each a In s
    v = Split(a, "=")
    If v(0) = "oauth_token_secret" Then
      GetOAuthToken_secret = v(1)
      Exit Function
    End If
  Next
End Function


hmacは前のエントリーのモジュールが必要です。

2011年2月15日火曜日

Scripting.Dictionaryオブジェクトのソート

あまり必要ありませんが、何かに使えるかもしれないのでメモ。

バリアント配列の初期化に誤りがあったので修正

Private Sub DicSort(ByRef dic As Scripting.Dictionary)
  Dim i As Long, j As Long
  Dim d As Variant
  Dim varTemp As Variant
  Dim varData() As Variant
  
  If dic Is Nothing And dic.Count = 0 Then
    Exit Sub
  End If
  
  'バリアント二次元配列
  ReDim varData(dic.Count - 1 , 1)
  i = 0
  For Each d In dic
    varData(i, 0) = d
    varData(i, 1) = dic(d)
    i = i + 1
  Next
  
  '総当りでソート(バブルソート)
  For i = 0 To dic.Count - 1
    For j = i + 1 To dic.Count - 1
      '比較
      If varData(i, 0) > varData(j, 0) Then
        '次の配列の値が小さい場合は入替
        varTemp = Array(varData(i, 0), varData(i, 1))
        varData(i, 0) = varData(j, 0)
        varData(i, 1) = varData(j, 1)
        varData(j, 0) = varTemp(0)
        varData(j, 1) = varTemp(1)
      End If
    Next
  Next
  
  dic.RemoveAll
  
  For i = 0 To UBound(varData)
    dic(varData(i, 0)) = varData(i, 1)
  Next
End Sub

エラーチェックはしていません。

2011年2月12日土曜日

vbaでhmac

とある事情からvbaのみでhmacができないか調べました。
で、できました。
スーの道具箱/気まぐれ日記/2007-03-08

VBでハッシュを求める *
MD5をVBで処理すると遅くなってしまうので、advapi32.dllを使うと簡単だし速い。
あまりサンプルが見当たらなかったので、書いてみた
ここからコピペして標準モジュールへ貼り付け。
おそらくExcel2000以上で動くと思います。
(vba6なら動くと思います)

Public Function hmac(ByVal key As String, ByVal data As String) As String
  Dim i As Integer
  Dim hash As String
  Dim key_byte() As Byte
  Dim key_len As Long
  Dim data_len As Long
  Dim ipad(63) As Byte
  Dim opad(63) As Byte
  Dim key_hash() As Byte
  Dim data_hash As String

  If key = "" And data = "" Then Exit Function

  key_len = Len(key)

  key_byte = StrConv(key, vbFromUnicode)
  If key_len > 64 Then
      key_hash = StrToBynary(CreateSHA1Hash(key_byte))
      key_len = 20
  Else
      key_hash = key_byte
  End If
  
  ReDim Preserve key_hash(63)
  For i = key_len To 63
    key_hash(i) = 0
  Next

  For i = 0 To 63
    ipad(i) = 0
    opad(i) = 0
  Next

  For i = 0 To 63
    ipad(i) = key_hash(i) Xor &H36
    opad(i) = key_hash(i) Xor &H5C
  Next

  data_hash = CreateSHA1Hash(CStr(ipad) & StrConv(data, vbFromUnicode))

  hash = CreateSHA1Hash(CStr(opad) & CStr(StrToBynary(data_hash)))

  hmac = hash
End Function

Private Function StrToBynary(strHexString As String) As Byte()
  Dim buf() As Byte
  Dim i As Long
  
  ReDim Preserve buf(Len(CStr(strHexString)) \ 2 - 1)
  For i = 0 To Len(CStr(strHexString)) \ 2 - 1
    buf(i) = CByte("&h" & Mid(CStr(strHexString), i * 2 + 1, 2))
  Next
  StrToBynary = buf
End Function


ここを参考にしました。
【Access】vbaでhmacが正しく計算できた!! | プラプラ式技術系 Access流!
HMAC SHA256 BASE64: 逢魔時 ~トワイライト~