From 0e65202f981b0125f2d40789432869871de1947f Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Wed, 16 May 2018 14:16:54 -0400 Subject: [PATCH] add bytes2hex(io, a) method --- NEWS.md | 3 +++ base/loading.jl | 5 +++-- base/strings/util.jl | 18 ++++++++++++++---- base/uuid.jl | 3 +-- test/loading.jl | 2 +- test/strings/util.jl | 2 +- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 16a93a529b1a9..019ed1af3f4f3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -478,6 +478,9 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286]). + * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream + without allocating a `String` first ([#27121]). + * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` inputs, it "steals" the memory buffer, leaving them with an empty buffer which is guaranteed not to be shared with the `String` object. For other types of vectors diff --git a/base/loading.jl b/base/loading.jl index 08a55b8c01405..d4d1355211921 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -91,10 +91,11 @@ struct SHA1 end end SHA1(s::AbstractString) = SHA1(hex2bytes(s)) + string(hash::SHA1) = bytes2hex(hash.bytes) -print(io::IO, hash::SHA1) = print(io, string(hash)) +print(io::IO, hash::SHA1) = bytes2hex(io, hash.bytes) +show(io::IO, hash::SHA1) = print(io, "SHA1(\"", hash, "\")") -show(io::IO, hash::SHA1) = print(io, "SHA1(\"", string(hash), "\")") isless(a::SHA1, b::SHA1) = lexless(a.bytes, b.bytes) hash(a::SHA1, h::UInt) = hash((SHA1, a.bytes), h) ==(a::SHA1, b::SHA1) = a.bytes == b.bytes diff --git a/base/strings/util.jl b/base/strings/util.jl index 5106105f7a8c6..9f2155fe403fc 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -547,10 +547,13 @@ end throw(ArgumentError("byte is not an ASCII hexadecimal digit")) """ - bytes2hex(bin_arr::Array{UInt8, 1}) -> String + bytes2hex(a::AbstractArray{UInt8}) -> String + bytes2hex(io::IO, a::AbstractArray{UInt8}) + +Convert an array `a` of bytes to its hexadecimal string representation, either +returning a `String` via `bytes2hex(a)` or writing the string to an `io` stream +via `bytes2hex(io, a)`. The hexadecimal characters are all lowercase. -Convert an array of bytes to its hexadecimal representation. -All characters are in lower-case. # Examples ```jldoctest julia> a = string(12345, base = 16) @@ -565,8 +568,10 @@ julia> bytes2hex(b) "3039" ``` """ +function bytes2hex end + function bytes2hex(a::AbstractArray{UInt8}) - b = Vector{UInt8}(undef, 2*length(a)) + b = Base.StringVector(2*length(a)) i = 0 for x in a b[i += 1] = hex_chars[1 + x >> 4] @@ -575,6 +580,11 @@ function bytes2hex(a::AbstractArray{UInt8}) return String(b) end +bytes2hex(io::IO, a::AbstractArray{UInt8}) = + for x in a + print(io, Char(hex_chars[1 + x >> 4]), Char(hex_chars[1 + x & 0xf])) + end + # check for pure ASCII-ness function ascii(s::String) diff --git a/base/uuid.jl b/base/uuid.jl index a1f3eb7c03f8d..cf422724eb928 100644 --- a/base/uuid.jl +++ b/base/uuid.jl @@ -50,8 +50,7 @@ let groupings = [36:-1:25; 23:-1:20; 18:-1:15; 13:-1:10; 8:-1:1] u = u.value a = Base.StringVector(36) for i in groupings - d = u & 0xf - a[i] = '0' + d + 39*(d > 9) + a[i] = hex_chars[1 + u & 0xf] u >>= 4 end a[24] = a[19] = a[14] = a[9] = '-' diff --git a/test/loading.jl b/test/loading.jl index aa1bd829b7396..7b77dfcca3cce 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -96,7 +96,7 @@ end let uuidstr = "ab"^4 * "-" * "ab"^2 * "-" * "ab"^2 * "-" * "ab"^2 * "-" * "ab"^6 uuid = UUID(uuidstr) @test uuid == eval(Meta.parse(repr(uuid))) # check show method - @test string(uuid) == uuidstr + @test string(uuid) == uuidstr == sprint(print, uuid) @test "check $uuid" == "check $uuidstr" end diff --git a/test/strings/util.jl b/test/strings/util.jl index e5d62bbdbb0a0..dcf949eec2666 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -324,7 +324,7 @@ end bin_val = hex2bytes(hex_str) @test div(length(hex_str), 2) == length(bin_val) - @test hex_str == bytes2hex(bin_val) + @test hex_str == bytes2hex(bin_val) == sprint(bytes2hex, bin_val) bin_val = hex2bytes("07bf") @test bin_val[1] == 7