using System; using System.Text; namespace Org.BouncyCastle.Utilities { /// General array utilities. public abstract class Arrays { public static bool AreEqual( bool[] a, bool[] b) { if (a == b) return true; if (a == null || b == null) return false; return HaveSameContents(a, b); } public static bool AreEqual( char[] a, char[] b) { if (a == b) return true; if (a == null || b == null) return false; return HaveSameContents(a, b); } /// /// Are two arrays equal. /// /// Left side. /// Right side. /// True if equal. public static bool AreEqual( byte[] a, byte[] b) { if (a == b) return true; if (a == null || b == null) return false; return HaveSameContents(a, b); } [Obsolete("Use 'AreEqual' method instead")] public static bool AreSame( byte[] a, byte[] b) { return AreEqual(a, b); } /// /// A constant time equals comparison - does not terminate early if /// test will fail. /// /// first array /// second array /// true if arrays equal, false otherwise. public static bool ConstantTimeAreEqual( byte[] a, byte[] b) { int i = a.Length; if (i != b.Length) return false; int cmp = 0; while (i != 0) { --i; cmp |= (a[i] ^ b[i]); } return cmp == 0; } public static bool AreEqual( int[] a, int[] b) { if (a == b) return true; if (a == null || b == null) return false; return HaveSameContents(a, b); } [CLSCompliantAttribute(false)] public static bool AreEqual(uint[] a, uint[] b) { if (a == b) return true; if (a == null || b == null) return false; return HaveSameContents(a, b); } private static bool HaveSameContents( bool[] a, bool[] b) { int i = a.Length; if (i != b.Length) return false; while (i != 0) { --i; if (a[i] != b[i]) return false; } return true; } private static bool HaveSameContents( char[] a, char[] b) { int i = a.Length; if (i != b.Length) return false; while (i != 0) { --i; if (a[i] != b[i]) return false; } return true; } private static bool HaveSameContents( byte[] a, byte[] b) { int i = a.Length; if (i != b.Length) return false; while (i != 0) { --i; if (a[i] != b[i]) return false; } return true; } private static bool HaveSameContents( int[] a, int[] b) { int i = a.Length; if (i != b.Length) return false; while (i != 0) { --i; if (a[i] != b[i]) return false; } return true; } private static bool HaveSameContents(uint[] a, uint[] b) { int i = a.Length; if (i != b.Length) return false; while (i != 0) { --i; if (a[i] != b[i]) return false; } return true; } public static string ToString( object[] a) { StringBuilder sb = new StringBuilder('['); if (a.Length > 0) { sb.Append(a[0]); for (int index = 1; index < a.Length; ++index) { sb.Append(", ").Append(a[index]); } } sb.Append(']'); return sb.ToString(); } public static int GetHashCode(byte[] data) { if (data == null) { return 0; } int i = data.Length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i]; } return hc; } public static int GetHashCode(int[] data) { if (data == null) return 0; int i = data.Length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= data[i]; } return hc; } [CLSCompliantAttribute(false)] public static int GetHashCode(uint[] data) { if (data == null) return 0; int i = data.Length; int hc = i + 1; while (--i >= 0) { hc *= 257; hc ^= (int)data[i]; } return hc; } public static byte[] Clone( byte[] data) { return data == null ? null : (byte[])data.Clone(); } public static byte[] Clone( byte[] data, byte[] existing) { if (data == null) { return null; } if ((existing == null) || (existing.Length != data.Length)) { return Clone(data); } Array.Copy(data, 0, existing, 0, existing.Length); return existing; } public static int[] Clone( int[] data) { return data == null ? null : (int[])data.Clone(); } public static long[] Clone(long[] data) { return data == null ? null : (long[])data.Clone(); } [CLSCompliantAttribute(false)] public static ulong[] Clone( ulong[] data) { return data == null ? null : (ulong[]) data.Clone(); } [CLSCompliantAttribute(false)] public static ulong[] Clone( ulong[] data, ulong[] existing) { if (data == null) { return null; } if ((existing == null) || (existing.Length != data.Length)) { return Clone(data); } Array.Copy(data, 0, existing, 0, existing.Length); return existing; } public static void Fill( byte[] buf, byte b) { int i = buf.Length; while (i > 0) { buf[--i] = b; } } public static byte[] Copy(byte[] data, int off, int len) { byte[] result = new byte[len]; Array.Copy(data, off, result, 0, len); return result; } } }