Class: IpaDiff::IpaStringsComparison

Inherits:
Object
  • Object
show all
Defined in:
lib/ipa_diff/ipa_strings_comparison.rb

Instance Method Summary collapse

Constructor Details

#initialize(ipa_path1, ipa_path2, verbose: false) ⇒ IpaStringsComparison

Returns a new instance of IpaStringsComparison.



9
10
11
12
13
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 9

def initialize(ipa_path1, ipa_path2, verbose: false)
  @ipa_path1 = ipa_path1
  @ipa_path2 = ipa_path2
  @verbose = verbose
end

Instance Method Details

#compare_ipa_strings(save_common_strings: false) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 47

def compare_ipa_strings(save_common_strings: false)
  dir1 = unzip_ipa(@ipa_path1)
  dir2 = unzip_ipa(@ipa_path2)

  strings1 = get_strings_from_directory(dir1)
  strings2 = get_strings_from_directory(dir2)

  common_strings = strings1 & strings2
  different_strings = (strings1 | strings2) - common_strings

  save_strings_to_file(common_strings, "common_strings.txt") if save_common_strings

  duplicates = find_files_with_same_sha256(dir1, dir2)

  {
    common_strings: common_strings,
    different_strings: different_strings,
    same_sha256: duplicates
  }
ensure
  FileUtils.remove_entry(dir1, true)
  FileUtils.remove_entry(dir2, true)
end

#compute_hash_files(files) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 89

def compute_hash_files(files)
  hash_files = {}

  files.each do |file|
    next unless File.file?(file)

    hash = Digest::SHA256.file(file).hexdigest
    hash_files[hash] ||= []
    hash_files[hash] << file
  end

  hash_files
end

#find_files_with_same_sha256(dir1, dir2) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 71

def find_files_with_same_sha256(dir1, dir2)
  files_dir1 = Dir.glob("#{dir1}/**/*")
  files_dir2 = Dir.glob("#{dir2}/**/*")

  hash_files_dir1 = compute_hash_files(files_dir1)
  hash_files_dir2 = compute_hash_files(files_dir2)

  common_files_hashes = hash_files_dir1.keys & hash_files_dir2.keys

  common_files_hashes.to_h do |sha256|
    files = hash_files_dir1[sha256] + hash_files_dir2[sha256]

    files.map! { |file| file.delete_prefix(dir1) }
    files.map! { |file| file.delete_prefix(dir2) }
    [sha256, files]
  end
end

#get_file_sha256(file_path) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 32

def get_file_sha256(file_path)
  digest = Digest::SHA256.new
  File.open(file_path, "rb") do |file|
    buffer = ""
    digest.update(buffer) while file.read(4096, buffer)
  end

  digest.hexdigest
end

#get_strings_from_binary(binary_path) ⇒ Object



42
43
44
45
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 42

def get_strings_from_binary(binary_path)
  strings = `strings "#{binary_path}"`.split("\n")
  strings.map(&:strip)
end

#unzip_ipa(ipa_path) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ipa_diff/ipa_strings_comparison.rb', line 15

def unzip_ipa(ipa_path)
  unzip_directory = Dir.mktmpdir

  puts "unzip_directory: ", unzip_directory if @verbose

  Zip::File.open(ipa_path) do |zip_file|
    zip_file.each do |entry|
      next if entry.name.start_with?("__MACOSX/")

      puts "Extracting #{entry.name}" if @verbose
      entry.extract(File.join(unzip_directory, entry.name))
    end
  end

  unzip_directory
end