나는 바이트를위한 "좋은"2 진수 연산자를 찾기 위해 몇 년 전에 쓴 프로그램을 가지고있다; 바이트 A
은 바이트 을 산출하기 위해 바이트 B
을 곱한 값으로 남습니다. 연산자는 256x256 바이트 행렬로 정의됩니다. A
클래스 구현의 버전을 아래에서 제거했습니다.==, CompareTo() 및 Equals()가 일치하지 않으면 어떻게됩니까?
Equals()
이 참 IFF 배열의 모든 65536 바이트는 동일합니다.
CompareTo()
은 연산자의 선형성을 더 선형 (cryto에 좋지 않음)에서 덜 선형 (crypto에 적합)으로 비교합니다.
A.Equals(B) = false
(A.ComparesTo(B) == 0) = true
내 질문이 작 : 이것은 좋은 생각이
은 그래서 다음에 모두 해당하는 것으로,이 경우, A
및 B
수 있습니까? 나는 대답이 '아니오'라는 것을 알고 있지만 선형성을 측정하기위한 많은 계산 비용과 내 문제의 좁은 특성을 감안할 때이 설계가 작동합니다. 비슷한 코드 :
if (localMinimumOperator < globalMinimumOperator)
{
localMinimumOperator = globalMinimumOperator;
}
더 읽기 쉽습니다.
내 질문입니다 : ==, CompareTo()== 0
및 Equals()
사이에 어떤 차이가 있습니까? 또는 대체적으로 : 어떤 인터페이스가 어떤 인터페이스를 사용하는지 설명하는 LINQ 확장 메서드 목록이 있습니까 (IEquatable
또는 IComparable
)?
Enumerable
에 대한이 MSDN 기사보다 더 간결한 내용이 있습니까? 예를 들어
:
IEnumerable<BinaryOperation> distinct = orgList.Distinct();
통화 당 Equals(BinaryOperator)
: Enumerable.Distinct<TSource>
MethodContains()
을 수행한다. Sort()
및 OrderBy()
은 CompareTo()
을 사용하는 것으로 알고 있습니다.
하지만 무엇에 대해 FindFirst()
및 BinarySearch()
?
내 예를 들어 클래스 :
사이에서이 차이의 결과는 무엇using System;
using System.Collections.Generic;
using System.Linq;
namespace Jww05
{
public class BinaryOperation : IEquatable<BinaryOperation>, IComparable<BinaryOperation>
{
#region ClassMembers
public List<List<byte>> TruthTable
{
get
{
// I don't like giving out the underlying list if I help it
var retVal = new List<List<byte>>(OperatorDefintion);
return retVal;
}
}
// private data store for TruthTable
private List<List<byte>> OperatorDefintion { get; set; }
public BinaryOperation()
{
// initial state is the Identity operator
OperatorDefintion = new List<List<byte>>();
for (int i = 0; i < 256; i++)
{
var curRow = new List<byte>();
for (int j = 0; j < 256; j++)
{
curRow.Add((byte)(i + j));
}
OperatorDefintion.Add(curRow);
}
}
private long MeasureOperatorLinearity()
{
var diagonalOffsets = new byte[] { 255, 0, 1 };
/*
* Code that measures linearity in the original code used the Fast Walsh Hadamard Transform.
* That should go here, but it is removed because the FWHT is clutter for the purposes of this question.
*
* Since I needed a stub for this, I decided to exacerbate the differnece
* between CompareTo() == 0 and Equals()
* by returning an arbitrary int in lieu of the long CPU intensive Fast Walsh Hadamard Transform.
*
* If the matrices are identical on an element-by-element basis, then the Faux Linearity will be the the same.
* If the faux linearity (sum of terms on the main diagonal and corners) are the same, the underlying matrices could be different on an element-by-element basis.
*/
long fauxLinearityMeasure = 0;
for (var currRow = 0; currRow < OperatorDefintion.Count(); ++currRow)
{
fauxLinearityMeasure *= 5;
fauxLinearityMeasure = diagonalOffsets.Select(diagonalOffset => (byte)(currRow + diagonalOffset))
.Aggregate(fauxLinearityMeasure, (current, offestedIndex) => current + (OperatorDefintion[offestedIndex][currRow]));
}
return (int)fauxLinearityMeasure;
}
#endregion ClassMembers
#region ComparisonOperations
public int CompareTo(BinaryOperation other)
{
long otherLinearity = other.MeasureOperatorLinearity();
long thisLinearity = MeasureOperatorLinearity();
long linearityDiff = thisLinearity - otherLinearity;
// case the differnece of the linarity measures into {-1, 0, 1}
return (0 < linearityDiff) ? 1
: (0 > linearityDiff) ? -1
: 0;
}
public static bool operator >(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 < lhs.CompareTo(rhs));
}
public static bool operator <(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 > lhs.CompareTo(rhs));
}
public static bool operator <=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
// equals is cheap
if (lhs.Equals(rhs))
{
return true;
}
return (0 > lhs.CompareTo(rhs));
}
public static bool operator >=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
// equals is cheap
if (lhs.Equals(rhs))
{
return true;
}
return (0 < lhs.CompareTo(rhs));
}
#endregion ComparisonOperations
#region EqualityOperators
public bool Equals(BinaryOperation other)
{
if (ReferenceEquals(null, other))
{
return false;
}
var otherTruthTable = other.TruthTable;
var thisTruthTable = TruthTable;
var isEquals = true;
for (int currRow = 0; currRow < thisTruthTable.Count(); ++currRow)
{
isEquals = isEquals && thisTruthTable[currRow].SequenceEqual(otherTruthTable[currRow]);
}
return isEquals;
}
public override bool Equals(object obj)
{
return Equals(obj as BinaryOperation);
}
public override int GetHashCode()
{
return OperatorDefintion.SelectMany(currRow => currRow)
.Aggregate(1, (current, currByte) => current * 5 + currByte);
}
public static bool operator ==(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 == lhs.CompareTo(rhs));
}
public static bool operator !=(BinaryOperation lhs, BinaryOperation rhs)
{
if (ReferenceEquals(null, lhs) ||
ReferenceEquals(null, rhs))
{
return false;
}
return (0 != lhs.CompareTo(rhs));
}
#endregion EqualityOperators
}
}
'=='은 정적이고 LINQ는 제네릭을 사용합니다. 그것은 섞이지 않습니다. 기껏해야 그것은 타입을 참조 타입으로 제한 할 수있다. 그렇다면'=='은 참조 평등을 의미 할 것이다. 사실 이것은 일반적인 제네릭에 대한 불만입니다. – harold
관심있는 사람들을 위해 [Linear Cryptanalysis] (http://en.wikipedia.org/wiki/Linear_cryptanalysis)에 내성이있는 연산자를 검색하기 위해 선형성 (affine distance)을 실제로 측정했습니다. –