C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

VBでCRC32を高速で計算する方法 [2]

[トピック内 95 記事 (41 - 60 表示)]  << 0 | 1 | 2 | 3 | 4 >>

■82394 / inTopicNo.41)  Re[22]: VBでCRC32を高速で計算する方法
  
□投稿者/ なちゃ (154回)-(2017/01/06(Fri) 10:15:58)
並列化の方はどうもキャッシュが安定してないですね…
遅い状態だとふつうにやるのと変わらなさそうです。
速いときは3割以上速くなりますね。

並列化は、そんな簡単な話じゃないので、上の日本語で理解できるようになってから作ってください。
今の状態では無理があります。
というかきっちり分かってないとバグバグになってどうにもならなくなりますよ。
引用返信 編集キー/
■82395 / inTopicNo.42)  Re[23]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (43回)-(2017/01/06(Fri) 10:26:41)
とりあえず
VBで書いた場合の
キーワードだけでもお教え願えないでしょうか?

引用返信 編集キー/
■82396 / inTopicNo.43)  Re[24]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (155回)-(2017/01/06(Fri) 11:32:38)
No82395 (ぎゅんぎゅ さん) に返信
> とりあえず
> VBで書いた場合の
> キーワードだけでもお教え願えないでしょうか?

先に書いたとおりにスレッド間で強調するなら普通にThreadを使ってスレッド開始、計算処理をワークとして扱うならTaskなどを使ってもよい。
スレッド間の協調はAutoResetEventなど。
ただしワークとしてTask使うなら特別使う必要はなさそう。

キーワードといってもこんな話で、スレッド関連のクラスの使い方だけ調べても意味が無く、それらの道具をどのように使って前の日本語で書いた処理を実装するかが肝です。
やり方はいくらでもあるので、キーワードだけ出してもあまり意味はありません。
引用返信 編集キー/
■82398 / inTopicNo.44)  Re[25]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (156回)-(2017/01/06(Fri) 15:19:44)
参考(見えるかな?)
md5のやつでc#ですが。

http://climbi.com/static/8894-0.txt
引用返信 編集キー/
■82399 / inTopicNo.45)  Re[26]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (157回)-(2017/01/06(Fri) 15:57:24)
No82398 (なちゃ さん) に返信
> 参考(見えるかな?)
> md5のやつでc#ですが。
>
> http://climbi.com/static/8894-0.txt

CRC32の実装としては、force-net Crc32で検索して出てくるのがかなり速そうです。
md5よりさらに速いです。
引用返信 編集キー/
■82400 / inTopicNo.46)  Re[27]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (158回)-(2017/01/06(Fri) 18:14:12)
No82399 (なちゃ さん) に返信
> ■No82398 (なちゃ さん) に返信
>>参考(見えるかな?)
>>md5のやつでc#ですが。
>>
>>http://climbi.com/static/8894-0.txt
>
> CRC32の実装としては、force-net Crc32で検索して出てくるのがかなり速そうです。
> md5よりさらに速いです。

この実装で並列化を行うと、MD5で単純に実行したときの倍くらいのパフォーマンスになってるので、もしかしたら0.6秒とかくらいで実行できるかも知れません。
まあ環境によるのでそんなには変わらないかも知れませんが。
引用返信 編集キー/
■82409 / inTopicNo.47)  Re[14]: VBでCRC32を高速で計算する方法
□投稿者/ Jitta (254回)-(2017/01/09(Mon) 09:39:33)
No82362 (ガラン さん) に返信
> ■No82361 (Jitta さん) に返信
>>ただ、CRCの結果がVB.NET、C#、C、どれも異なるんだよなぁ。
>>ウェブからコピペしただけなのになぁ。。。
>
> CRCはシフトの方向や初期値、生成多項式によって結果が変わります。
> コピペするだけじゃなくてちゃんと理解してプログラムを書いてください。
> ちゃんとやってください。(煽ってみる)
>

すみません、今見ました。
煽られてたw
ここの質問は「スピードアップ」とか「クロスランゲージ」なので、「それぞれの結果が異なってるんじゃないの?」という問題提起をすれば、後は質問者さんの問題でしょ、と思っていたのですが。

計算式が違うのかなぁ?と、C#、VB.NET のコードを見比べましたが、違いは無いように思いました。
次に、テーブルの値が違うのかな?と、これを出力すると、 No82332 の VB.NET のコード、 No82337 のリンク先にある C# のコード、 No82360 のコードに埋め込まれている値が、それぞれ異なっていました。私が作った C のコードは、Wikipediaの「巡回冗長検査」のページにあるものです。No82360のコードは入力していないので、これとの差異は見ていません。また、C が作る値も、まだ見ていません。
とりあえず、C# と VB.NET を合わせることを目的に、テーブル生成のところを見直したのですが、式は同じように思いました。
ということは、VB.NET と C# で、何らかの式の結果が異なるのでは?と見当をつけました。
すると、「If (DWCRC And 1) Then」これが、期待する結果と異なるようだとわかりました。
というか、Option Strict On にしても、これ、警告されないのね。
C/C++, C# の三項演算子にあたる If 演算子では、警告されました。
If で判定するのはブール値なので、「DWCRC And 1」の結果得られる整数値から暗黙変換できない、ということです。
ここを修正すると、C# と VB.NET で一致するようになりました。(ほかにも、いろいろ修正したので、ここだけではないかも。)
引用返信 編集キー/
■82411 / inTopicNo.48)  Re[15]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (44回)-(2017/01/09(Mon) 22:17:30)
みなさん、ご回答ありがとうございます。

もう少し調べて、勉強してみてから
分からないことを再度質問いたします。

とりあえず閉じさせていただきます。
 
解決済み
引用返信 編集キー/
■82414 / inTopicNo.49)  Re[16]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (159回)-(2017/01/10(Tue) 09:58:48)
No82411 (ぎゅんぎゅ さん) に返信
> みなさん、ご回答ありがとうございます。
>
> もう少し調べて、勉強してみてから
> 分からないことを再度質問いたします。
>
> とりあえず閉じさせていただきます。

乗りかかった船なので、一応VB版も上げておきました。
Md5直実行の倍速くらいは出てますね。

http://climbi.com/static/8921-0.txt

NuGetなどでCrc32.NET入手したらコンパイルできます。
https://www.nuget.org/packages/Crc32.NET/
引用返信 編集キー/
■82422 / inTopicNo.50)  Re[17]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (45回)-(2017/01/10(Tue) 13:04:12)
ありがとうございます。

http://kazenetu.exblog.jp/19671851/

このページを参考に
Crc32 for .NET
のインストールを試みたのですが

以下のエラーが出てしまいます。

c:\>nuget.exe Install Crc32.NET
Attempting to resolve dependency 'NETStandard.Library (? 1.3.0)'.
'NETStandard.Library' already has a dependency defined for 'Microsoft.NETCore.Pl
atforms'.

一体何が原因でしょうか?






引用返信 編集キー/
■82426 / inTopicNo.51)  Re[18]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (160回)-(2017/01/10(Tue) 14:25:01)
Visual Studio上からソリューションのNuGetパッケージの管理とかそういうメニューを使ったほうが簡単だと思いますよ。
オンラインからCrc32とかで検索すると、多分いくつかヒットしますが探せると思います。

もしくは、NuGet使わずにリポジトリから直にダウンロードして参照設定とかでもいいです。
以下辺りからダウンロードできます。
https://github.com/force-net/Crc32.NET/releases
引用返信 編集キー/
■82427 / inTopicNo.52)  Re[19]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (161回)-(2017/01/10(Tue) 14:28:14)
あ、一つ忘れてましたが、プログラム内のtaskになってるクラスは、System.Threading.Tasks.Taskのことなので、ファイル先頭などでImportsするか、フルクラス名に書き換えてください。

引用返信 編集キー/
■82428 / inTopicNo.53)  Re[20]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (46回)-(2017/01/10(Tue) 15:05:55)
ツール→拡張機能マネージャーで
NuGet Packagerはインストールしたのですが
検索画面等が出てこないのですが・・・

http://www.atmarkit.co.jp/fdotnet/chushin/nuget_01/nuget_01_01.html
 インストールが完了すると、Visual Studioの(メニューバーの)[ツール]メニューに[Library Package Manager]というメニュー項目が追加される。

と書かれてあるのですが
ツールには何も追加されないのですが・・・

あと、直にDLする方法ですが
VS2016で作成されたコードであるため
私のVS2010では開くことができませんでした
VS2016をインストールして自分でビルドしないと使えないでしょうか?

 
引用返信 編集キー/
■82430 / inTopicNo.54)  Re[21]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (162回)-(2017/01/10(Tue) 16:02:23)
No82428 (ぎゅんぎゅ さん) に返信
> ツール→拡張機能マネージャーで
> NuGet Packagerはインストールしたのですが
> 検索画面等が出てこないのですが・・・
>
> http://www.atmarkit.co.jp/fdotnet/chushin/nuget_01/nuget_01_01.html
>  インストールが完了すると、Visual Studioの(メニューバーの)[ツール]メニューに[Library Package Manager]というメニュー項目が追加される。
>
> と書かれてあるのですが
> ツールには何も追加されないのですが・・・
>
> あと、直にDLする方法ですが
> VS2016で作成されたコードであるため
> 私のVS2010では開くことができませんでした
> VS2016をインストールして自分でビルドしないと使えないでしょうか?


NuGetの方ですが、ソリューションを右クリックのメニューからパッケージの管理関連のメニューでないですかね?

直ダウンロードの方ですが、コンパイル対象のソースは2本しかないですので、VS2010でクラスライブラリのプロジェクトを自作して、ダウンロードしたソースコード2本をプロジェクトに追加するだけでもいけます。
※要はプロジェクトは自分で作成してしまう。
この方法が一番手っ取り早いかも知れません。
引用返信 編集キー/
■82431 / inTopicNo.55)  Re[22]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (47回)-(2017/01/10(Tue) 16:33:46)
なちゃ さん

何から何までありがとうございます。

> NuGetの方ですが、ソリューションを右クリックのメニューからパッケージの管理関連のメニューでないですかね?
というのはなぜか出てきませんでしたが、

C#で自分でビルドする方法でうまくいきました。

ところで、なぜかこの方法だと
CRCの前に「0」が付くことがあるのですが
これはどうすれば良いでしょうか?
毎回付くわけではありません。
 
引用返信 編集キー/
■82433 / inTopicNo.56)  Re[23]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (48回)-(2017/01/10(Tue) 17:11:13)
すいません、
あと大きなファイルサイズの場合には問題ないのですが
1kB以下の小さなファイルサイズのファイルの場合
一回読み込ませた場合にはCRCが取得できず
二回やらないと取得できないのですが
なぜでしょうか?
 
引用返信 編集キー/
■82435 / inTopicNo.57)  Re[24]: VBでCRC32を高速で計算する方法
□投稿者/ なちゃ (163回)-(2017/01/10(Tue) 17:55:33)
No82433 (ぎゅんぎゅ さん) に返信
> すいません、
> あと大きなファイルサイズの場合には問題ないのですが
> 1kB以下の小さなファイルサイズのファイルの場合
> 一回読み込ませた場合にはCRCが取得できず
> 二回やらないと取得できないのですが
> なぜでしょうか?
>  

ごめんなさい、大きいファイルでしか試してなかったので、クロージャ用の変数宣言位置がまずかったのに気づいてませんでした。

以下修正してみた版です。
http://climbi.com/static/8921.txt

最初にゼロが付くというのは、もしかしたらバイト配列から文字列への変換がまずいのかも知れません(未確認)。
他の人の変換コードで試してみた方がいいのかも。


引用返信 編集キー/
■82436 / inTopicNo.58)  Re[25]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (49回)-(2017/01/10(Tue) 18:28:43)
なちゃ さん

うまくいきました。
ありがとうございます。

前に0がつくというのは、私の勘違いでした。
別のプログラムでやると0がつかなかったので、
そちらが正しいのだと思っていたのですが
そうではなく
0が付いたまま表示するこちらのプログラムの方が正しいことが分かりました。

小さなファイルサイズのファイルも問題無く読み込むことができました。
 
引用返信 編集キー/
■82438 / inTopicNo.59)  Re[26]: VBでCRC32を高速で計算する方法
□投稿者/ ぎゅんぎゅ (50回)-(2017/01/10(Tue) 18:33:11)

なちゃさん


C#のDLLを読み込む方法でうまくいったのですが
後学のためにVBコードに変換しても実行してみたいと考えています。

SharpDevelopを使うことで
ほとんどエラーなく以下のようにVBコードに変換することができました。


Namespace Force_Crc32
Friend Class SafeProxy
Private Const Poly As UInteger = &HEDB88320UI

Private Shared ReadOnly _table As UInteger() = New UInteger(16 * 256 - 1) {}

Shared Sub New()
For i As UInteger = 0 To 255
Dim res As UInteger = i
For t As Integer = 0 To 15
For k As Integer = 0 To 7
res = If((res And 1) = 1, Poly Xor (res >> 1), (res >> 1))
Next
_table((t * 256) + i) = res
Next
Next
End Sub

Public Function Append(ByVal crc As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
Dim crcLocal As UInteger = UInteger.MaxValue Xor crc

Dim table As UInteger() = _table
While length >= 16
crcLocal = table((15 * 256) + ((crcLocal Xor input(offset)) And &HFF)) _
Xor table((14 * 256) + (((crcLocal >> 8) Xor input(offset + 1)) And &HFF)) _
Xor table((13 * 256) + (((crcLocal >> 16) Xor input(offset + 2)) And &HFF)) _
Xor table((12 * 256) + (((crcLocal >> 24) Xor input(offset + 3)) And &HFF)) _
Xor table((11 * 256) + input(offset + 4)) _
Xor table((10 * 256) + input(offset + 5)) _
Xor table((9 * 256) + input(offset + 6)) _
Xor table((8 * 256) + input(offset + 7)) _
Xor table((7 * 256) + input(offset + 8)) _
Xor table((6 * 256) + input(offset + 9)) _
Xor table((5 * 256) + input(offset + 10)) _
Xor table((4 * 256) + input(offset + 11)) _
Xor table((3 * 256) + input(offset + 12)) _
Xor table((2 * 256) + input(offset + 13)) _
Xor table((1 * 256) + input(offset + 14)) _
Xor table((0 * 256) + input(offset + 15))
offset += 16
length -= 16
End While

While System.Threading.Interlocked.Decrement(length) >= 0
crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8
End While
Return crcLocal Xor UInteger.MaxValue
End Function
End Class
End Namespace




Imports System
Imports System.Security.Cryptography

Namespace Force_Crc32
''' <summary>
''' Implementation of CRC-32.
''' This class supports several convenient static methods returning the CRC as UInt32.
''' </summary>
Public Class Crc32Algorithm
Inherits HashAlgorithm
Private _currentCrc As UInteger

''' <summary>
''' Initializes a new instance of the <see cref="Crc32Algorithm"/> class.
''' </summary>
Public Sub New()
#If Not NETCORE Then
#End If
HashSizeValue = 32
End Sub

''' <summary>
''' Computes CRC-32 from multiple buffers.
''' Call this method multiple times to chain multiple buffers.
''' </summary>
''' <param name="initial">
''' Initial CRC value for the algorithm. It is zero for the first buffer.
''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
''' </param>
''' <param name="input">Input buffer with data to be checksummed.</param>
''' <param name="offset">Offset of the input data within the buffer.</param>
''' <param name="length">Length of the input data in the buffer.</param>
''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
Public Shared Function Append(ByVal initial As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
If input Is Nothing Then
Throw New ArgumentNullException()
End If
If offset < 0 OrElse length < 0 OrElse offset + length > input.Length Then
Throw New ArgumentOutOfRangeException("Selected range is outside the bounds of the input array")
End If
Return AppendInternal(initial, input, offset, length)
End Function

''' <summary>
''' Computes CRC-3C from multiple buffers.
''' Call this method multiple times to chain multiple buffers.
''' </summary>
''' <param name="initial">
''' Initial CRC value for the algorithm. It is zero for the first buffer.
''' Subsequent buffers should have their initial value set to CRC value returned by previous call to this method.
''' </param>
''' <param name="input">Input buffer containing data to be checksummed.</param>
''' <returns>Accumulated CRC-32 of all buffers processed so far.</returns>
Public Shared Function Append(ByVal initial As UInteger, ByVal input As Byte()) As UInteger
If input Is Nothing Then
Throw New ArgumentNullException()
End If
Return AppendInternal(initial, input, 0, input.Length)
End Function

''' <summary>
''' Computes CRC-32 from input buffer.
''' </summary>
''' <param name="input">Input buffer with data to be checksummed.</param>
''' <param name="offset">Offset of the input data within the buffer.</param>
''' <param name="length">Length of the input data in the buffer.</param>
''' <returns>CRC-32 of the data in the buffer.</returns>
Public Shared Function Compute(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
Return Append(0, input, offset, length)
End Function

''' <summary>
''' Computes CRC-32 from input buffer.
''' </summary>
''' <param name="input">Input buffer containing data to be checksummed.</param>
''' <returns>CRC-32 of the buffer.</returns>
Public Shared Function Compute(ByVal input As Byte()) As UInteger
Return Append(0, input)
End Function

''' <summary>
''' Resets internal state of the algorithm. Used internally.
''' </summary>
Public Overrides Sub Initialize()
_currentCrc = 0
End Sub

''' <summary>
''' Appends CRC-32 from given buffer
''' </summary>
Protected Overrides Sub HashCore(ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer)
_currentCrc = AppendInternal(_currentCrc, input, offset, length)
End Sub

''' <summary>
''' Computes CRC-32 from <see cref="HashCore"/>
''' </summary>
Protected Overrides Function HashFinal() As Byte()
' Crc32 by dariogriffo uses big endian, so, we need to be compatible and return big endian too
Return New Byte() {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)}
End Function

Private Shared ReadOnly _proxy As New SafeProxy()

Private Shared Function AppendInternal(ByVal initial As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
If length > 0 Then
Return _proxy.Append(initial, input, offset, length)
Else
Return initial
End If
End Function
End Class
End Namespace


しかし、実行しても、
エラーは出ないのですが、0しか返しません。

なにが原因でしょうか?

ちなみにSharpDevelopでコードを変換後に

Return New () {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)}

res = If((res And 1) is 1, Poly Xor (res >> 1), (res >> 1))

でエラーが出たので
それぞれ以下のように変更しました

Return New Byte() {CByte(_currentCrc >> 24), CByte(_currentCrc >> 16), CByte(_currentCrc >> 8), CByte(_currentCrc)}

res = If((res And 1) = 1, Poly Xor (res >> 1), (res >> 1))





引用返信 編集キー/
■82441 / inTopicNo.60)  Re[27]: VBでCRC32を高速で計算する方法
 
□投稿者/ 魔界の仮面弁士 (1040回)-(2017/01/10(Tue) 20:08:31)
No82438 (ぎゅんぎゅ さん) に返信
> Public Function Append(ByVal crc As UInteger, ByVal input As Byte(), ByVal offset As Integer, ByVal length As Integer) As UInteger
VB には「Input 関数」が存在するので、input という引数名ではなく、別の名前にした方が良いですね。
予約語ではないので、この名前のままでもエラーにはなりませんけれども。


>> crcLocal = table[(crcLocal ^ input[offset++]) & 0xff] ^ crcLocal >> 8;
> crcLocal = table((crcLocal Xor input(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1))) And &HFF) Xor crcLocal >> 8

C# の「offset++」と
VB の「System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1)」は
等価では無いので、ここは修正が必要ですね。


下記の C# コードは、「33」「44」を出力します。

int[] ary = new int[] { 11, 22, 33, 44, 55 };
int offset = 2;
Console.WriteLine(ary[offset++]);
Console.WriteLine(ary[offset++]);



下記の VB コードは、「44」「55」です。

Dim ary As Integer() = New Integer() {11, 22, 33, 44, 55}
Dim offset As Integer = 2
Console.WriteLine(ary(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1)))
Console.WriteLine(ary(System.Math.Max(System.Threading.Interlocked.Increment(offset), offset - 1)))


> Public Sub New()
>  #If Not NETCORE Then
>  #End If
>  HashSizeValue = 32
> End Sub


この部分、元の C# コードに合わせるなら

Public Sub New()
 #If Not NETCORE Then
  HashSizeValue = 32
 #End If
End Sub

ではありませんか?


> しかし、実行しても、
> エラーは出ないのですが、0しか返しません。
> なにが原因でしょうか?

先のインクリメント部分を直してみてください。
それと、このコードをどのようにして呼び出していますか?


> でエラーが出たので
> それぞれ以下のように変更しました

この誤訳は SharpDevelop の問題っぽいですね。
引用返信 編集キー/

このトピックをツリーで一括表示

<前の20件 | 次の20件>
トピック内ページ移動 / << 0 | 1 | 2 | 3 | 4 >>

管理者用

- Child Tree -